﻿///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2023, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Область ОписаниеПеременных

&НаКлиенте
Перем ОбработчикПослеФормированияНаКлиенте Экспорт;
&НаКлиенте
Перем ВыполнятьЗамеры;
&НаКлиенте
Перем ИдентификаторЗамера;
&НаКлиенте
Перем Непосредственно;
&НаКлиенте
Перем ФормированиеПриОткрытии;
&НаКлиенте
Перем ИнтервалОжидания;
&НаКлиенте
Перем РезультатНастройки;
&НаСервере
Перем ПараметрыЗагрузкиПередУстановкойТекущегоВарианта;

#КонецОбласти

#Область ОбработчикиСобытийФормы

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

	ОпределитьПоведениеВМобильномКлиенте();

	РежимРасшифровки = Параметры.Расшифровка <> Неопределено Или Параметры.ПредставлениеВарианта = "Расшифровка";

	ПравоВывода = ПравоДоступа("Вывод", Метаданные);

	ОтчетОбъект     = РеквизитФормыВЗначение("Отчет");
	ОтчетМетаданные = ОтчетОбъект.Метаданные();
	ОтчетПолноеИмя  = ОтчетМетаданные.ПолноеИмя();

	КонтекстВарианта = КонтекстВариантаОтчета();
	УстановитьКлючНазначенияИспользования();
	СохранитьПараметрыФормы();
	
	// Определение настроек отчета.
	ТипОтчетаСтрокой = ВариантыОтчетов.ТипОтчетаСтрокой(Параметры.Отчет);
	Если ТипОтчетаСтрокой = Неопределено Тогда
		Информация      = ВариантыОтчетов.ИнформацияОбОтчете(ОтчетПолноеИмя, Истина);
		Параметры.Отчет = Информация.Отчет;
	КонецЕсли;

	УстановитьКлючТекущегоВарианта(ОтчетПолноеИмя, ОтчетОбъект);
	ФормаПараметры.НачальныйКлючВарианта = КлючТекущегоВарианта;

	НастройкиОтчета = НастройкиОтчета(ОтчетОбъект);

	ОбновитьИнформациюОВариантеОтчета();
	ФормаПараметры.НачальныйКлючПредопределенногоВарианта = НастройкиОтчета.КлючПредопределенногоВарианта;

	Если Параметры.СформироватьПриОткрытии Тогда
		Параметры.СформироватьПриОткрытии = Ложь;
		Элементы.ФормироватьСразу.Пометка = Истина;
		НастройкиОтчета.ПрочитатьФлажокФормироватьСразуИзПользовательскихНастроек = Ложь;
	КонецЕсли;

	Если ОбщегоНазначения.ЭтоВебКлиент() Тогда
		Элементы.ПредварительныйПросмотр.Видимость = Ложь;
	КонецЕсли;
	
	// Параметры по умолчанию.
	Если Не НастройкиОтчета.ВыводитьСуммуВыделенныхЯчеек Или НастройкиОтчета.ОтключитьСтандартноеКонтекстноеМеню Тогда
		Элементы.ГруппаПоказатель.Видимость = Ложь;
		Элементы.ОбластьПоказателей.Видимость = Ложь;
		Элементы.КомандыВидовПоказателейЕще.Видимость = Ложь;
		Элементы.КоманднаяПанельЕще.РастягиватьПоГоризонтали = Неопределено;
	КонецЕсли;

	УстановитьРазрешенияПользователя();
	
	// Регистрация команд и реквизитов формы, которые не удаляются при перезаполнении быстрых настроек.
	НаборРеквизитов = ПолучитьРеквизиты();
	Для Каждого Реквизит Из НаборРеквизитов Цикл
		ПолноеИмяРеквизита = Реквизит.Имя + ?(ПустаяСтрока(Реквизит.Путь), "", "." + Реквизит.Путь);
		ПостоянныеРеквизиты.Добавить(ПолноеИмяРеквизита);
	КонецЦикла;

	Для Каждого Команда Из Команды Цикл
		ПостоянныеКоманды.Добавить(Команда.Имя);
	КонецЦикла;

	Если Не ВариантыОтчетовСлужебныйКлиентСервер.РежимВариантаОтчета(КлючТекущегоВарианта) Тогда
		УстановитьВидимостьДоступность();
	КонецЕсли;

	ПроверитьДоступностьОбменаНастройкамиВарианта(ОтчетМетаданные);
	
	// Тесная интеграция с почтой и рассылкой.
	ДоступнаОтправкаПисем = Ложь;
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.РаботаСПочтовымиСообщениями") Тогда
		МодульРаботаСПочтовымиСообщениями = ОбщегоНазначения.ОбщийМодуль("РаботаСПочтовымиСообщениями");
		ДоступнаОтправкаПисем = МодульРаботаСПочтовымиСообщениями.ДоступнаОтправкаПисем();
	КонецЕсли;

	Если ДоступнаОтправкаПисем Тогда
		Если НастройкиОтчета.РазрешеноИзменятьВарианты И ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.РассылкаОтчетов") 
			И ВариантыОтчетов.ОтчетПодключенКХранилищу(РеквизитФормыВЗначение("Отчет").Метаданные()) 
			И Не НастройкиОтчета.СкрытьКомандыРассылки Тогда

			МодульРассылкаОтчетов = ОбщегоНазначения.ОбщийМодуль("РассылкаОтчетов");
			МодульРассылкаОтчетов.ФормаОтчетаДобавитьКоманды(ЭтотОбъект, Отказ, СтандартнаяОбработка);
		Иначе // Если в подменю одна команда, то выпадающий список не отображается.
			Элементы.ОтправитьПоПочте.Заголовок = Элементы.ГруппаОтправить.Заголовок + "...";
			Элементы.Переместить(Элементы.ОтправитьПоПочте, Элементы.ГруппаОтправить.Родитель, Элементы.ГруппаОтправить);
		КонецЕсли;
	Иначе
		Элементы.ГруппаОтправить.Видимость = Ложь;
	КонецЕсли;
	
	// Определение, что отчет может содержать некорректные данные.
	Если Не Элементы.ФормироватьСразу.Пометка Тогда
		Попытка
			ИспользуемыеТаблицы = ВариантыОтчетов.ИспользуемыеТаблицы(ОтчетОбъект.СхемаКомпоновкиДанных);
			ИспользуемыеТаблицы.Добавить(НастройкиОтчета.ПолноеИмя);

			Если НастройкиОтчета.События.ПриОпределенииИспользуемыхТаблиц Тогда
				ОтчетОбъект.ПриОпределенииИспользуемыхТаблиц(КлючТекущегоВарианта, ИспользуемыеТаблицы);
			КонецЕсли;

			ВариантыОтчетов.ПроверитьИспользуемыеТаблицы(ИспользуемыеТаблицы);
		Исключение
			ТекстОшибки = НСтр("ru = 'Не удалось определить используемые таблицы:'");
			ТекстОшибки = ТекстОшибки + Символы.ПС + ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
			ВариантыОтчетов.ЗаписатьВЖурнал(УровеньЖурналаРегистрации.Ошибка, ТекстОшибки,
				НастройкиОтчета.ВариантСсылка);
		КонецПопытки;
	КонецЕсли;

	ОтчетыКлиентСервер.ОтобразитьСостояниеОтчета(
		ЭтотОбъект, НСтр("ru = 'Отчет не сформирован. Нажмите ""Сформировать"" для получения отчета.'"));

	ИнтеграцияПодсистемБСП.ПриСозданииНаСервереВариантыОтчетов(ЭтотОбъект, Отказ, СтандартнаяОбработка);
	ОтчетыПереопределяемый.ПриСозданииНаСервере(ЭтотОбъект, Отказ, СтандартнаяОбработка);
	Если НастройкиОтчета.События.ПриСозданииНаСервере Тогда
		ОтчетОбъект.ПриСозданииНаСервере(ЭтотОбъект, Отказ, СтандартнаяОбработка);
	КонецЕсли;

	Элементы.ПраваПользователей.Видимость = Пользователи.ЭтоПолноправныйПользователь()
		И ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.УправлениеДоступом");

	ЗаполнитьПутьКФайлуВнешнегоОтчетаНаКлиенте(ОтчетОбъект);

КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)
#Если ВебКлиент Тогда
	Если ЗначениеЗаполнено(ПутьКФайлуВнешнегоОтчетаНаКлиенте) Тогда
		ТекстОшибки = НСтр("ru = 'Для этого действия требуется запустить клиентское приложение'");
		ВызватьИсключение ТекстОшибки;
	КонецЕсли;
#КонецЕсли
	ВыполнятьЗамеры = Ложь;
	
	// В безопасном режиме доп. отчеты формируются непосредственно,
	// т.к. они не могут подключать себя и использовать собственные методы в фоновых заданиях.
	Непосредственно = НастройкиОтчета.Внешний Или НастройкиОтчета.Безопасный;
	ФормированиеПриОткрытии = Ложь;
	ИнтервалОжидания = ?(ПолучитьСкоростьКлиентскогоСоединения() = СкоростьКлиентскогоСоединения.Низкая, 1, 0.2);

	Если Элементы.ФормироватьСразу.Пометка Тогда
		ФормированиеПриОткрытии = Истина;
		ПодключитьОбработчикОжидания("Сформировать", 0.1, Истина);
	Иначе
		СброситьТекущуюОбласть();
	КонецЕсли;

	ОбщегоНазначенияСлужебныйКлиент.УстановитьВидимостьПанелиПоказателей(Элементы, РазвернутьОбластьПоказателей);
	РассчитатьПоказатели(ОсновнойПоказатель);

	ПодключитьОбработчикОжидания("ОпределитьПоведениеНаНачальнойСтранице", 0.1, Истина);
КонецПроцедуры

&НаКлиенте
Процедура ОбработкаВыбора(Результат, ПодчиненнаяФорма)
	РезультатОбработан = Ложь;
	
	// Приемка результата из стандартных форм.
	Если ТипЗнч(ПодчиненнаяФорма) = Тип("ФормаКлиентскогоПриложения") Тогда

		ИмяПодчиненнойФормы = ПодчиненнаяФорма.ИмяФормы;
		Если ИмяПодчиненнойФормы = "ХранилищеНастроек.ХранилищеВариантовОтчетов.Форма.НастройкиОтчета"
			Или ПодчиненнаяФорма.ОписаниеОповещенияОЗакрытии <> Неопределено Тогда

			РезультатОбработан = Истина; // См. ПрименитьНастройкиИПереформироватьОтчет.

		ИначеЕсли ТипЗнч(Результат) = Тип("Структура") Тогда

			ЧастиИмениФормы = СтрРазделить(ИмяПодчиненнойФормы, ".");
			ИмяФормыИсточника = ВРег(ЧастиИмениФормы[ЧастиИмениФормы.Количество() - 1]);
			Если ИмяФормыИсточника = ВРег("ФормаНастроекОтчета") Или ИмяФормыИсточника = ВРег("ФормаНастроек")
				Или ИмяФормыИсточника = ВРег("ФормаВариантаОтчета") Или ИмяФормыИсточника = ВРег("ФормаВарианта") Тогда

				ОбновитьЭлементыФормыНастроек(Результат);
				РезультатОбработан = Истина;
			КонецЕсли;
		КонецЕсли;

		ПрименитьНастройкиИзКонтекстногоМеню(Результат);

	ИначеЕсли ТипЗнч(ПодчиненнаяФорма) = Тип("КонструкторСхемыКомпоновкиДанных") Тогда

		ПрименитьСхемуИзКонструктора(Результат);

	КонецЕсли;
	
	// Механизмы расширения.
	Если ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.РассылкаОтчетов") Тогда
		МодульРассылкаОтчетовКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("РассылкаОтчетовКлиент");
		МодульРассылкаОтчетовКлиент.ФормаОтчетаОбработкаВыбора(ЭтотОбъект, Результат, ПодчиненнаяФорма,
			РезультатОбработан);
	КонецЕсли;
	ИнтеграцияПодсистемБСПКлиент.ПриОбработкеВыбора(ЭтотОбъект, Результат, ПодчиненнаяФорма, РезультатОбработан);
	ОтчетыКлиентПереопределяемый.ОбработкаВыбора(ЭтотОбъект, Результат, ПодчиненнаяФорма, РезультатОбработан);
КонецПроцедуры

&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
	ОповещениеОбработано = Ложь;

	Если ИмяСобытия = "Запись_НаборКонстант" Тогда

		ОповещениеОбработано = Истина;
		ВариантыПанелиКлючТекущегоВарианта = ПустойКлючВарианта();

	ИначеЕсли ИмяСобытия = ВариантыОтчетовКлиент.ИмяСобытияИзменениеВарианта() Тогда

		ОповещениеОбработано = Истина;
		КлючВарианта = Неопределено;
		НастройкиОтчета.КлючСхемы = "";

		Если ТипЗнч(Параметр) = Тип("Структура") Тогда
			Параметр.Свойство("КлючВарианта", КлючВарианта);
		КонецЕсли;

		Если ЗначениеЗаполнено(КлючВарианта) Тогда
			УстановитьТекущийВариант(КлючВарианта);
		Иначе
			ВариантыПанелиКлючТекущегоВарианта = ПустойКлючВарианта();
		КонецЕсли;

		ОтключитьОбработчикОжидания("ОбновитьКомандыВыбораВариантовОбработчикОжидания");
		ПодключитьОбработчикОжидания("ОбновитьКомандыВыбораВариантовОбработчикОжидания", 2, Истина);

	ИначеЕсли ИмяСобытия = ВариантыОтчетовКлиентСервер.ИмяДействияПрименитьПереданныеНастройки() Тогда

		ОповещениеОбработано = Истина;
		ПрименитьПереданныеНастройки(Параметр);

	ИначеЕсли ИмяСобытия = "ИзменениеВидимостиВариантаОтчетаВПанелиОтчетов" И Параметр = НастройкиОтчета.ПолноеИмя
		И ВариантыОтчетовСлужебныйКлиентСервер.РежимВариантаОтчета(КлючТекущегоВарианта)
		И НастройкиОтчета.РазрешеноВыбиратьВарианты Тогда

		ОтключитьОбработчикОжидания("ОбновитьКомандыВыбораВариантовОбработчикОжидания");
		ПодключитьОбработчикОжидания("ОбновитьКомандыВыбораВариантовОбработчикОжидания", 2, Истина);
		Возврат;

	КонецЕсли;

	ПрименитьНастройкиИзКонтекстногоМеню(Параметр);

	ИнтеграцияПодсистемБСПКлиент.ПриОбработкеОповещения(ЭтотОбъект, ИмяСобытия, Параметр, Источник,
		ОповещениеОбработано);
	ОтчетыКлиентПереопределяемый.ОбработкаОповещения(ЭтотОбъект, ИмяСобытия, Параметр, Источник, ОповещениеОбработано);
КонецПроцедуры

&НаСервере
Процедура ПередЗагрузкойВариантаНаСервере(НовыеНастройкиКД)
	// Ничего не делать если отчет не на СКД и никаких настроек не загружено.
	Если НовыеНастройкиКД = Неопределено Или Не ВариантыОтчетовСлужебныйКлиентСервер.РежимВариантаОтчета(
		КлючТекущегоВарианта) Тогда

		Возврат;
	КонецЕсли;

	ДополнительныеСвойства = НовыеНастройкиКД.ДополнительныеСвойства;

	Если ВариантыПанелиКлючТекущегоВарианта <> КлючТекущегоВарианта Тогда
		ДополнительныеСвойства.Удалить("КлючВарианта");
		ДополнительныеСвойства.Удалить("КлючПредопределенногоВарианта");
		ДополнительныеСвойства.Удалить("КонтекстВарианта");
		ДополнительныеСвойства.Удалить("ФормаПараметрыОтбор");
		ДополнительныеСвойства.Удалить("ВариантНаименование");
	КонецЕсли;

	Если РежимРасшифровки Тогда
		Если ТипЗнч(Параметры.Расшифровка) = Тип("ОписаниеОбработкиРасшифровкиКомпоновкиДанных") Тогда
			ВариантыОтчетовСлужебный.ПодготовитьНастройкиОтчетаКРасшифровкеПоДетальнымЗаписям(
				ЭтотОбъект, НовыеНастройкиКД, Параметры.Расшифровка.ПрименяемыеНастройки);
		КонецЕсли;

		Если ЗначениеЗаполнено(КлючТекущегоВарианта) Тогда
			ДополнительныеСвойства.Вставить("КлючВарианта", КлючТекущегоВарианта);
		КонецЕсли;
	КонецЕсли;

	ИнтеграцияПодсистемБСП.ПередЗагрузкойВариантаНаСервере(ЭтотОбъект, НовыеНастройкиКД);
	ОтчетыПереопределяемый.ПередЗагрузкойВариантаНаСервере(ЭтотОбъект, НовыеНастройкиКД);
	Если НастройкиОтчета.События.ПередЗагрузкойВариантаНаСервере Тогда
		ОтчетОбъект = РеквизитФормыВЗначение("Отчет");
		ОтчетОбъект.ПередЗагрузкойВариантаНаСервере(ЭтотОбъект, НовыеНастройкиКД);
	КонецЕсли;
	
	// Подготовка к вызову события переинициализации.
	Если НастройкиОтчета.События.ПередЗагрузкойНастроекВКомпоновщик Тогда
		Попытка
			НовыеНастройкиXML = ОбщегоНазначения.ЗначениеВСтрокуXML(НовыеНастройкиКД);
		Исключение
			НовыеНастройкиXML = Неопределено;
		КонецПопытки;
		НастройкиОтчета.НовыеНастройкиXML = НовыеНастройкиXML;
	КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ПриЗагрузкеВариантаНаСервере(НовыеНастройкиКД)
	// Если отчет не на СКД и никаких настроек не загружено.
	Если Не ВариантыОтчетовСлужебныйКлиентСервер.РежимВариантаОтчета(КлючТекущегоВарианта) И НовыеНастройкиКД = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	// Загрузка фиксированных настроек для режима расшифровки.
	Если РежимРасшифровки Тогда
		ОтчетНаименованиеТекущегоВарианта = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(
			НовыеНастройкиКД.ДополнительныеСвойства, "ВариантНаименование");

		Если ТипЗнч(Параметры.Расшифровка) = Тип("ОписаниеОбработкиРасшифровкиКомпоновкиДанных") Тогда
			Отчет.КомпоновщикНастроек.ЗагрузитьФиксированныеНастройки(Параметры.Расшифровка.ПрименяемыеНастройки);
			Отчет.КомпоновщикНастроек.ФиксированныеНастройки.ДополнительныеСвойства.Вставить("РежимРасшифровки", Истина);
		КонецЕсли;

		Если КлючТекущегоВарианта = Неопределено Тогда
			КлючТекущегоВарианта = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(
				НовыеНастройкиКД.ДополнительныеСвойства, "КлючВарианта");
		КонецЕсли;
	КонецЕсли;
	
	// Установка фиксированных отборов выполняется через компоновщик, т.к. в нем наиболее полная коллекция настроек.
	// В ПередЗагрузкой в параметрах могут отсутствовать те параметры, настройки которых не переопределялись.
	Если ВариантыОтчетов.ДопустимоУстановитьКонтекст(ЭтотОбъект) И ТипЗнч(ФормаПараметры.Отбор) = Тип("Структура") Тогда

		ОтчетыСервер.УстановитьФиксированныеОтборы(ФормаПараметры.Отбор, Отчет.КомпоновщикНастроек.Настройки,
			НастройкиОтчета);
	КонецЕсли;
	
	// Обновление ссылки варианта отчета.
	Если ВариантыПанелиКлючТекущегоВарианта <> КлючТекущегоВарианта Тогда
		ОбновитьИнформациюОВариантеОтчета();
	КонецЕсли;

	Если НастройкиОтчета.События.ПриЗагрузкеВариантаНаСервере Тогда
		ОтчетОбъект = РеквизитФормыВЗначение("Отчет");
		ОтчетОбъект.ПриЗагрузкеВариантаНаСервере(ЭтотОбъект, НовыеНастройкиКД);
	КонецЕсли;

	Если ЭтоМобильныйКлиент Тогда
		РасположениеРесурсов = Отчет.КомпоновщикНастроек.Настройки.ПараметрыВывода.НайтиЗначениеПараметра(
			Новый ПараметрКомпоновкиДанных("РасположениеРесурсов"));
		Если РасположениеРесурсов.Использование И РасположениеРесурсов.Значение = РасположениеРесурсовКомпоновкиДанных.Вертикально Тогда
			Элементы.ДекорацияИзменитьРасположениеРесурсов.Заголовок = НСтр("ru='Горизонтально'");
		КонецЕсли;
	КонецЕсли;

КонецПроцедуры

&НаСервере
Процедура ПередЗагрузкойПользовательскихНастроекНаСервере(НовыеПользовательскиеНастройкиКД)
	Если НастройкиОтчета.События.ПередЗагрузкойНастроекВКомпоновщик Тогда
		Попытка
			НовыеПользовательскиеНастройкиXML = ОбщегоНазначения.ЗначениеВСтрокуXML(НовыеПользовательскиеНастройкиКД);
		Исключение
			НовыеПользовательскиеНастройкиXML = Неопределено;
		КонецПопытки;
		НастройкиОтчета.НовыеПользовательскиеНастройкиXML = НовыеПользовательскиеНастройкиXML;
	КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ПриЗагрузкеПользовательскихНастроекНаСервере(НовыеПользовательскиеНастройкиКД)
	Если Не ВариантыОтчетовСлужебныйКлиентСервер.РежимВариантаОтчета(КлючТекущегоВарианта) Тогда
		Возврат;
	КонецЕсли;

	Если НастройкиОтчета.События.ПриЗагрузкеПользовательскихНастроекНаСервере Тогда
		ОтчетОбъект = РеквизитФормыВЗначение("Отчет");
		ОтчетОбъект.ПриЗагрузкеПользовательскихНастроекНаСервере(ЭтотОбъект, НовыеПользовательскиеНастройкиКД);
	КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ПриОбновленииСоставаПользовательскихНастроекНаСервере(СтандартнаяОбработка)
	КлючНастроек = КлючНастроекВариантаОтчета(НастройкиОтчета.ПолноеИмя, КлючТекущегоВарианта);
	ВосстановитьВыбранныйУровеньГруппировок(КлючНастроек, ВыбранныйУровеньГруппировок, РежимРасшифровки);

	Если Не ВариантыОтчетовСлужебныйКлиентСервер.РежимВариантаОтчета(КлючТекущегоВарианта) Тогда
		Возврат;
	КонецЕсли;

	СтандартнаяОбработка = Ложь;

	Если Не ВариантМодифицирован Тогда
		ВосстановитьСостояниеОпцииВыводитьЗаголовкиНастроек(КлючНастроек, ВыводитьЗаголовкиНастроек, РежимРасшифровки);
	КонецЕсли;

	ПараметрыОбновления = Новый Структура("ИмяСобытия", "ПриОбновленииСоставаПользовательскихНастроекНаСервере");
	ОбновитьЭлементыФормыНастроекНаСервере(ПараметрыОбновления);
КонецПроцедуры

&НаСервере
Процедура ОбработкаПроверкиЗаполненияНаСервере(Отказ, ПроверяемыеРеквизиты)
	Если Не ВариантыОтчетовСлужебныйКлиентСервер.РежимВариантаОтчета(КлючТекущегоВарианта) Тогда
		Возврат;
	КонецЕсли;

	Если ПутьКДаннымЭлементов = Неопределено Тогда
		Возврат;
	КонецЕсли;

	ЭлементыНастроек = Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы;
	Для Каждого ЭлементНастройки Из ЭлементыНастроек Цикл
		Если ТипЗнч(ЭлементНастройки) <> Тип("ЗначениеПараметраНастроекКомпоновкиДанных") 
			Или ТипЗнч(ЭлементНастройки.Значение) <> Тип("СтандартныйПериод") 
			Или Не ЭлементНастройки.Использование Тогда
			Продолжить;
		КонецЕсли;

		ШаблонИмени = ПутьКДаннымЭлементов.ПоИндексу[ЭлементыНастроек.Индекс(ЭлементНастройки)];
		Если ШаблонИмени = Неопределено Тогда
			Продолжить;
		КонецЕсли;

		ДатаНачала = Элементы.Найти(ШаблонИмени + "ДатаНачала");
		ДатаОкончания = Элементы.Найти(ШаблонИмени + "ДатаОкончания");
		Если ДатаНачала = Неопределено Или ДатаОкончания = Неопределено Тогда
			Продолжить;
		КонецЕсли;

		Значение = ЭлементНастройки.Значение; // СтандартныйПериод
		Если ДатаНачала.АвтоОтметкаНезаполненного = Истина И Не ЗначениеЗаполнено(Значение.ДатаНачала)
			И Не ЗначениеЗаполнено(Значение.ДатаОкончания) Тогда
			ТекстОшибки = НСтр("ru = 'Не указан период'");
			ПутьКДанным = ДатаНачала.ПутьКДанным;
		ИначеЕсли Значение.ДатаНачала > Значение.ДатаОкончания Тогда
			ТекстОшибки = НСтр("ru = 'Конец периода должен быть больше начала'");
			ПутьКДанным = ДатаОкончания.ПутьКДанным;
		Иначе
			Продолжить;
		КонецЕсли;

		ОбщегоНазначения.СообщитьПользователю(ТекстОшибки,, ПутьКДанным,, Отказ);
	КонецЦикла;
КонецПроцедуры

&НаСервере
Процедура ПриЗагрузкеДанныхИзНастроекНаСервере(Настройки)
	Значение = Настройки["ФормаНастроекРасширенныйРежим"];
	Если Значение <> Неопределено Тогда
		Если Значение = 1 И Не НастройкиОтчета.РазрешеноИзменятьСтруктуру Тогда
			Возврат;
		КонецЕсли;
		НастройкиОтчета.ФормаНастроекРасширенныйРежим = Значение;
	КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ПриСохраненииДанныхВНастройкахНаСервере(Настройки)

	СохранитьДанныеВНастройкахНаСервере(Настройки);

КонецПроцедуры

&НаСервере
Процедура ПриСохраненииВариантаНаСервере(НастройкиКД)
	Если Не ВариантыОтчетовСлужебныйКлиентСервер.РежимВариантаОтчета(КлючТекущегоВарианта) Тогда
		Возврат;
	КонецЕсли;

	НовыеНастройкиКД = Отчет.КомпоновщикНастроек.ПолучитьНастройки();
	ОтчетыКлиентСервер.ЗагрузитьНастройки(Отчет.КомпоновщикНастроек, НовыеНастройкиКД);
	НастройкиКД.ДополнительныеСвойства.Вставить("Адрес", ПоместитьВоВременноеХранилище(НовыеНастройкиКД));
	НастройкиКД = НовыеНастройкиКД;
	ВариантыПанелиКлючТекущегоВарианта = ПустойКлючВарианта();
	ОбновитьИнформациюОВариантеОтчета();
	УстановитьВидимостьДоступность();
	ОбновитьДополнительныеСвойстваДанныхРасшифровки();

	Если ОбщегоНазначения.ЭтоВебКлиент() Тогда
		СохранитьДанныеВНастройкахНаСервере();
	КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ПриСохраненииПользовательскихНастроекНаСервере(ПользовательскиеНастройкиКД)
	Если Не ВариантыОтчетовСлужебныйКлиентСервер.РежимВариантаОтчета(КлючТекущегоВарианта) Тогда
		Возврат;
	КонецЕсли;
	ВариантыОтчетов.ПриСохраненииПользовательскихНастроекНаСервере(ЭтотОбъект, ПользовательскиеНастройкиКД);
	ОбновитьКомандыВыбораВариантов();
КонецПроцедуры

#Если МобильныйКлиент Тогда

&НаКлиенте
Процедура ПриИзмененииДоступностиОсновногоСервера(СтандартнаяОбработка)

	Если ОсновнойСерверДоступен() = Ложь Тогда
		ОткрытьФорму("РегистрСведений.СнимкиОтчетов.Форма.ФормаПросмотраОтчетов");
		Закрыть();
	КонецЕсли;

КонецПроцедуры

#КонецЕсли

#КонецОбласти

#Область ОбработчикиСобытийЭлементовШапкиФормы

////////////////////////////////////////////////////////////////////////////////
// Подключаемые

&НаКлиенте
Процедура Подключаемый_ЭлементНастройки_ПриИзменении(Элемент)
	КомпоновщикНастроек = Отчет.КомпоновщикНастроек;

	Индекс = ПутьКДаннымЭлементов.ПоИмени[Элемент.Имя];
	Если Индекс = Неопределено Тогда
		Индекс = ОтчетыКлиентСервер.ИндексЭлементаНастройкиПоПути(Элемент.Имя);
	КонецЕсли;

	ЭлементНастройки = КомпоновщикНастроек.ПользовательскиеНастройки.Элементы[Индекс];

	ЭтоФлажок = СтрНачинаетсяС(Элемент.Имя, "Флажок") Или СтрЗаканчиваетсяНа(Элемент.Имя, "Флажок");
	Если ЭтоФлажок Тогда
		ЭлементНастройки.Значение = ЭтотОбъект[Элемент.Имя];
	КонецЕсли;

	Если ТипЗнч(ЭлементНастройки) = Тип("ЗначениеПараметраНастроекКомпоновкиДанных")
		И НастройкиОтчета.ЗагрузитьНастройкиПриИзмененииПараметров.Найти(ЭлементНастройки.Параметр) <> Неопределено Тогда

		ВариантБылМодифицирован = ВариантМодифицирован;
		КомпоновщикНастроек.Настройки.ДополнительныеСвойства.Вставить("ОтчетИнициализирован", Ложь);
		ВариантМодифицирован = ВариантБылМодифицирован;
		ПараметрыИзменены = Истина;

		ПараметрыОбновления = Новый Структура;
		ПараметрыОбновления.Вставить("КомпоновщикНастроекКД", КомпоновщикНастроек);
		ПараметрыОбновления.Вставить("ПользовательскиеНастройкиМодифицированы", Истина);
		ОбновитьЭлементыФормыНастроек(ПараметрыОбновления);

	КонецЕсли;

	ОтчетыКлиентСервер.ОповеститьОИзмененииНастроек(ЭтотОбъект);
КонецПроцедуры

&НаКлиенте
Процедура Подключаемый_ЭлементНастройки_НачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
	ПараметрыИзменены = Истина;
	ПоказатьСписокВыбора(Элемент, СтандартнаяОбработка);
КонецПроцедуры

&НаКлиенте
Процедура Подключаемый_Период_ПриИзменении(Элемент)
	ПараметрыИзменены = Истина;
	ОтчетыКлиент.УстановитьПериод(ЭтотОбъект, Элемент.Имя);
КонецПроцедуры

&НаКлиенте
Процедура Подключаемый_ВыбратьПериод(Команда)
	ПараметрыИзменены = Истина;
	ОтчетыКлиент.ВыбратьПериод(ЭтотОбъект, Команда.Имя);
КонецПроцедуры

&НаКлиенте
Процедура Подключаемый_СдвинутьПериодНазад(Команда)
	ПараметрыИзменены = Истина;
	ОтчетыКлиент.СдвинутьПериод(ЭтотОбъект, Команда.Имя);
КонецПроцедуры

&НаКлиенте
Процедура Подключаемый_СдвинутьПериодВперед(Команда)
	ПараметрыИзменены = Истина;
	ОтчетыКлиент.СдвинутьПериод(ЭтотОбъект, Команда.Имя);
КонецПроцедуры

#Область ОбработчикиСобытийЭлементовУниверсальнойСтрокиПоиска

&НаКлиенте
Процедура ПоказательРасширеннаяПодсказкаОбработкаНавигационнойСсылки(Элемент, НавигационнаяСсылкаФорматированнойСтроки,
	СтандартнаяОбработка)

	СтандартнаяОбработка = Ложь;

	Если Элементы.ВсеНастройки.Видимость Тогда
		ПерейтиКНастройкам(НастройкиОтчета.РазрешеноИзменятьВарианты);
	Иначе
		ПоказатьПредупреждение(, НСтр("ru = 'Расширенные возможности настройки фильтров недоступны'"));
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура ПоказательПриИзменении(Элемент)

	ПереходКНастройкамВыполнен();

КонецПроцедуры

&НаКлиенте
Процедура ПоказательОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)

	Если ТипЗнч(ВыбранноеЗначение) <> Тип("Массив") Тогда
		СброситьУниверсальныйПоиск();
		Возврат;
	КонецЕсли;

	СтандартнаяОбработка = Ложь;
	ПрименитьЗначениеУниверсальногоПоиска(ВыбранноеЗначение);

КонецПроцедуры

&НаКлиенте
Процедура ПоказательАвтоПодбор(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, Ожидание, СтандартнаяОбработка)

	Если Не ЗначениеЗаполнено(Текст) Тогда
		Возврат;
	КонецЕсли;

	Запрос = СокрЛП(Текст);

	Если ПереходКНастройкамВыполнен(Запрос) Тогда
		Возврат;
	КонецЕсли;

	ПодходящиеЗначения = ПодходящиеЗначенияУниверсальногоПоиска(Запрос);

	Если ПодходящиеЗначения.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;

	ДанныеВыбора = ПодходящиеЗначения;
	СтандартнаяОбработка = Ложь;

КонецПроцедуры

#КонецОбласти

#Область ОбработчикиСобытийДокументаОтчетТабличныйДокумент

&НаКлиенте
Процедура ОтчетТабличныйДокументВыбор(Элемент, Область, СтандартнаяОбработка)

	ОбработкаРасшифровки = Ложь;

	Если СтандартнаяОбработка Тогда
		ИнтеграцияПодсистемБСПКлиент.ПриОбработкеВыбораТабличногоДокумента(ЭтотОбъект, Элемент, Область,
			СтандартнаяОбработка);
		ОтчетыКлиентПереопределяемый.ОбработкаВыбораТабличногоДокумента(ЭтотОбъект, Элемент, Область,
			СтандартнаяОбработка);
	КонецЕсли;

	Если Не ОбработкаРасшифровки И СтандартнаяОбработка И ТипЗнч(Область) = Тип("ОбластьЯчеекТабличногоДокумента") Тогда

		Если ПерейтиПоСсылке(Область.Текст) Тогда
			СтандартнаяОбработка = Ложь;
			Возврат;
		КонецЕсли;

		Попытка
			ЗначениеРасшифровки = Область.Расшифровка;
		Исключение
			ЗначениеРасшифровки = Неопределено;
			// Для некоторых типов областей табличного документа (свойство ТипОбласти)
			// чтение расшифровки недоступно, поэтому делается попытка-исключение.
		КонецПопытки;

		Если ЗначениеРасшифровки <> Неопределено И ПерейтиПоСсылке(ЗначениеРасшифровки) Тогда
			СтандартнаяОбработка = Ложь;
			Возврат;
		КонецЕсли;

		Если ПерейтиПоСсылке(Область.Маска) Тогда
			СтандартнаяОбработка = Ложь;
			Возврат;
		КонецЕсли;
	КонецЕсли;

	Если Не ОбработкаРасшифровки И СтандартнаяОбработка Тогда
		ВариантыОтчетовСлужебныйКлиент.ПоказатьКонтекстнуюНастройкуОтчета(ЭтотОбъект, Элемент, Область,
			СтандартнаяОбработка);
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура ОтчетТабличныйДокументОбработкаРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка)

	ИнтеграцияПодсистемБСПКлиент.ПриОбработкеРасшифровки(ЭтотОбъект, Элемент, Расшифровка, СтандартнаяОбработка);
	ОтчетыКлиентПереопределяемый.ОбработкаРасшифровки(ЭтотОбъект, Элемент, Расшифровка, СтандартнаяОбработка);

	Если СтандартнаяОбработка Тогда
		ВариантыОтчетовСлужебныйКлиент.ОбработкаРасшифровки(ЭтотОбъект, Элемент, Расшифровка, СтандартнаяОбработка);
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура ОтчетТабличныйДокументОбработкаДополнительнойРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка)

	Если ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.АнализЖурналаРегистрации") Тогда
		МодульАнализЖурналаРегистрацииКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("АнализЖурналаРегистрацииКлиент");
		МодульАнализЖурналаРегистрацииКлиент.ФормаОтчетаОбработкаДополнительнойРасшифровки(ЭтотОбъект, Элемент,
			Расшифровка, СтандартнаяОбработка);
	КонецЕсли;

	ИнтеграцияПодсистемБСПКлиент.ПриОбработкеДополнительнойРасшифровки(ЭтотОбъект, Элемент, Расшифровка,
		СтандартнаяОбработка);
	ОтчетыКлиентПереопределяемый.ОбработкаДополнительнойРасшифровки(ЭтотОбъект, Элемент, Расшифровка,
		СтандартнаяОбработка);

	Если СтандартнаяОбработка Тогда
		Данные = ДанныеЭлементаРасшифровки(Расшифровка);
		ВариантыОтчетовСлужебныйКлиент.ОбработкаДополнительнойРасшифровки(ЭтотОбъект, Данные, Элемент, Расшифровка,
			СтандартнаяОбработка);
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура ОтчетТабличныйДокументПриАктивизации(Элемент)

	ВариантыОтчетовСлужебныйКлиент.ПриАктивизацииРезультатаОтчета(ЭтотОбъект, Элементы.ОтчетТабличныйДокумент);
	ПодключитьОбработчикОжидания("РассчитатьПоказателиДинамически", 0.2, Истина);

КонецПроцедуры

&НаКлиенте
Процедура ОтчетТабличныйДокументПередЗаписью(Элемент, Копирование, Отказ)

	Отказ = Истина;
	СохранитьОтчет(Команды.Найти(Элементы.СохранитьОтчет.ИмяКоманды));

КонецПроцедуры

#КонецОбласти

#КонецОбласти

#Область ОбработчикиКомандФормы

&НаКлиенте
Процедура ВсеНастройки(Команда)

	ПерейтиКНастройкам();

КонецПроцедуры

&НаКлиенте
Процедура ПрименитьНастройкиИПереформироватьОтчет(Результат, ПараметрыВыполнения) Экспорт
	Если ТипЗнч(Результат) <> Тип("Структура") Тогда
		Возврат;
	КонецЕсли;

	Если Результат.Свойство("ИмяСобытия") 
		И Результат.ИмяСобытия = ВариантыОтчетовСлужебныйКлиентСервер.ИмяСобытияФормыНастроек() 
		И Результат.ВариантМодифицирован Тогда

		ВариантыОтчетовСлужебныйКлиент.ДобавитьНастройкиВСтек(
			ЭтотОбъект, Результат.КомпоновщикНастроекКД.Настройки, Результат.ИмяСобытия);

	КонецЕсли;

	РезультатНастройки = Результат;
	ОтчетСформирован = Результат.Переформировать;

	ПодключитьОбработчикОжидания("ОбновитьЭлементыФормыНастроекОтложенно", 0.1, Истина);
КонецПроцедуры

&НаКлиенте
Процедура НастройкиПоУмолчанию(Команда)
	ПараметрыЗаполнения = Новый Структура;
	ПараметрыЗаполнения.Вставить("ИмяСобытия", ОтчетыКлиентСервер.ИмяСобытияНастройкиПоУмолчанию());

	Если ВариантМодифицирован
	 Или НастройкиОтчета.ПолноеИмя = "Отчет.УниверсальныйОтчет" Тогда
		ПараметрыЗаполнения.Вставить("СброситьНастройкиВарианта", Истина);
		ПараметрыЗаполнения.Вставить("ВариантМодифицирован", Ложь);
	КонецЕсли;

	ПараметрыЗаполнения.Вставить("СброситьПользовательскиеНастройки", Истина);
	ПараметрыЗаполнения.Вставить("ПользовательскиеНастройкиМодифицированы", Истина);

	ОтчетСформирован = Ложь;

	СброситьВыбранныйУровеньГруппировок();
	ВариантыОтчетовСлужебныйКлиент.СброситьПометкиСтекаНастроек(СтекНастроек);
	ОбновитьЭлементыФормыНастроек(ПараметрыЗаполнения);
КонецПроцедуры

&НаКлиенте
Процедура СохранитьВариант(Команда)

	Если Не ВариантМодифицирован
	   И НастройкиОтчета.ПолноеИмя <> "Отчет.УниверсальныйОтчет" Тогда
		Возврат;
	КонецЕсли;

	СохранитьВариантОтчета();

КонецПроцедуры

&НаКлиенте
Процедура ОтправитьПоПочте(Команда)
	ОтображениеСостояния = Элементы.ОтчетТабличныйДокумент.ОтображениеСостояния;
	Если ОтображениеСостояния.Видимость = Истина 
		И ОтображениеСостояния.ДополнительныйРежимОтображения = ДополнительныйРежимОтображения.Неактуальность Тогда
		ТекстВопроса = НСтр("ru = 'Отчет не сформирован. Сформировать?'");
		Обработчик = Новый ОписаниеОповещения("СформироватьПередОтправкойПоПочте", ЭтотОбъект);
		ПоказатьВопрос(Обработчик, ТекстВопроса, РежимДиалогаВопрос.ДаНет, 60, КодВозвратаДиалога.Да);
	Иначе
		ПоказатьДиалогОтправкиПоПочте();
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ОтчетСкомпоноватьРезультат(Команда)
	ОчиститьСообщения();
	Сформировать();
	ПараметрыИзменены = Ложь;
КонецПроцедуры

&НаКлиенте
Процедура ФормироватьСразу(Команда)
	ФормироватьСразу = Не Элементы.ФормироватьСразу.Пометка;
	Элементы.ФормироватьСразу.Пометка = ФормироватьСразу;

	СостояниеДоИзменения = Новый Структура("Видимость, ДополнительныйРежимОтображения, Картинка, Текст");
	ЗаполнитьЗначенияСвойств(СостояниеДоИзменения, Элементы.ОтчетТабличныйДокумент.ОтображениеСостояния);

	Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.ДополнительныеСвойства.Вставить("ФормироватьСразу",
		ФормироватьСразу);
	ПользовательскиеНастройкиМодифицированы = Истина;

	ЗаполнитьЗначенияСвойств(Элементы.ОтчетТабличныйДокумент.ОтображениеСостояния, СостояниеДоИзменения);
КонецПроцедуры

&НаКлиенте
Процедура ДругиеОтчеты(Команда)
	ОписаниеНастроекОтчета = ОписаниеНастроекОтчета(НастройкиОтчета);

	ВидимыеВарианты = Новый Массив;
	Для Каждого Строка Из ДобавленныеВарианты Цикл
		ВидимыеВарианты.Добавить(Строка.Ссылка);
	КонецЦикла;

	ПараметрыФормы = Новый Структура;
	ПараметрыФормы.Вставить("ВариантСсылка", НастройкиОтчета.ВариантСсылка);
	ПараметрыФормы.Вставить("ОтчетСсылка", НастройкиОтчета.ОтчетСсылка);
	ПараметрыФормы.Вставить("ПодсистемаСсылка", ФормаПараметры.Подсистема);
	ПараметрыФормы.Вставить("ОтчетНаименование", ОписаниеНастроекОтчета.Наименование);
	ПараметрыФормы.Вставить("ВидимыеВарианты", Новый ФиксированныйМассив(ВидимыеВарианты));
	
	ОткрытьФорму("ХранилищеНастроек.ХранилищеВариантовОтчетов.Форма.ПанельДругихОтчетов", ПараметрыФормы, ЭтотОбъект,
		Истина,,,, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
		
КонецПроцедуры

&НаКлиенте
Процедура ИзменитьСоставБыстрыхНастроек(Команда)

	ПараметрыФормы = Новый Структура;
	ПараметрыФормы.Вставить("НастройкиОтчета", НастройкиОтчета);
	ПараметрыФормы.Вставить("КомпоновщикНастроек", Отчет.КомпоновщикНастроек);
	ПараметрыФормы.Вставить("КлючТекущегоВарианта", КлючТекущегоВарианта);
	ПараметрыФормы.Вставить("ВыводитьЗаголовкиНастроек", ВыводитьЗаголовкиНастроек);

	Обработчик = Новый ОписаниеОповещения("ПослеИзмененияСоставаБыстрыхНастроек", ЭтотОбъект);
	ОткрытьФорму("ХранилищеНастроек.ХранилищеВариантовОтчетов.Форма.БыстрыеНастройкиОтчета", ПараметрыФормы,
		ЭтотОбъект, УникальныйИдентификатор,,, Обработчик);

КонецПроцедуры

&НаКлиенте
Процедура ИзменитьРасположениеРесурсов(Команда)

	РасположениеРесурсов = Элементы.ДекорацияИзменитьРасположениеРесурсов.Заголовок;
	ЗначениеПараметра = Отчет.КомпоновщикНастроек.Настройки.ПараметрыВывода.НайтиЗначениеПараметра(
		Новый ПараметрКомпоновкиДанных("РасположениеРесурсов"));
	Если ЗначениеПараметра <> Неопределено Тогда
		ЗначениеПараметра.Использование = Истина;
		ЗначениеПараметра.Значение = РасположениеРесурсовКомпоновкиДанных[РасположениеРесурсов];
	КонецЕсли;
	Элементы.ДекорацияИзменитьРасположениеРесурсов.Заголовок = ?(РасположениеРесурсов = "Вертикально", "Горизонтально",
		"Вертикально");

	ОчиститьСообщения();
	Сформировать();

КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// Обработчики команд модификации СКД.

&НаКлиенте
Процедура ЗагрузитьСхему(Команда)

	ОписаниеОповещения = Новый ОписаниеОповещения("ЗагрузитьСхемуПослеПомещенияФайла", ЭтотОбъект);

	ПараметрыЗагрузки = ФайловаяСистемаКлиент.ПараметрыЗагрузкиФайла();
	ПараметрыЗагрузки.Диалог.Фильтр = НСтр("ru = 'Файлы XML (*.xml) |*.xml'");
	ПараметрыЗагрузки.ИдентификаторФормы = УникальныйИдентификатор;

	ФайловаяСистемаКлиент.ЗагрузитьФайл(ОписаниеОповещения, ПараметрыЗагрузки);

КонецПроцедуры

&НаКлиенте
Процедура РедактироватьСхему(Команда)
#Если ТолстыйКлиентОбычноеПриложение Или ТолстыйКлиентУправляемоеПриложение Тогда
	СхемаКомпоновкиДанных = ПолучитьИзВременногоХранилища(НастройкиОтчета.АдресСхемы);

	Если СхемаКомпоновкиДанных.НастройкиПоУмолчанию.ДополнительныеСвойства.Свойство("СхемаКомпоновкиДанных") Тогда
		СхемаКомпоновкиДанных.НастройкиПоУмолчанию.ДополнительныеСвойства.СхемаКомпоновкиДанных = Неопределено;
	КонецЕсли;

	Конструктор = Новый КонструкторСхемыКомпоновкиДанных(СхемаКомпоновкиДанных);
	Конструктор.Редактировать(ЭтотОбъект);
#Иначе
	ПоказатьПредупреждение(, НСтр("ru = 'Для того чтобы редактировать схему компоновки, запустите приложение в режиме толстого клиента.'"));
#КонецЕсли
КонецПроцедуры

&НаКлиенте
Процедура ВосстановитьСтандартнуюСхему(Команда)
	Отчет.КомпоновщикНастроек.Настройки.ДополнительныеСвойства.Очистить();

	Если НастройкиОтчета.ПолноеИмя = "Отчет.УниверсальныйОтчет" Тогда
		ПараметрыДанных = Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы;
		ИменаПараметровКОчистке = СтрРазделить("ТипОбъектаМетаданных, ИмяОбъектаМетаданных, ИмяТаблицы", ", ", Ложь);
		Для Каждого ИмяПараметра Из ИменаПараметровКОчистке Цикл
			НайденныйПараметр = ПараметрыДанных.Найти(ИмяПараметра);
			Если НайденныйПараметр <> Неопределено Тогда
				НайденныйПараметр.Значение = Неопределено;
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;

	ПараметрыЗаполнения = Новый Структура;
	ПараметрыЗаполнения.Вставить("КомпоновщикНастроекКД", Отчет.КомпоновщикНастроек);
	ПараметрыЗаполнения.Вставить("ПользовательскиеНастройкиМодифицированы", Истина);

	ОбновитьЭлементыФормыНастроек(ПараметрыЗаполнения);
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// Обработчики команд обмена настройками (основными и пользовательскими).

&НаКлиенте
Процедура СохранитьВариантОтчетаВФайл(Команда)
	ОткрытьФорму("ХранилищеНастроек.ХранилищеВариантовОтчетов.Форма.СохранениеВариантаОтчетаВФайл",
		ВариантыОтчетовСлужебныйКлиент.ПараметрыСохраненияВариантаОтчетаВФайл(ЭтотОбъект), ЭтотОбъект);
КонецПроцедуры

&НаКлиенте
Процедура ОбновитьВариантОтчетаИзФайла(Команда)

	СвойстваВариантаОтчета = ВариантыОтчетовКлиент.СвойстваВариантаОтчетаОснования();
	СвойстваВариантаОтчета.Ссылка = НастройкиОтчета.ВариантСсылка;
	СвойстваВариантаОтчета.ИмяОтчета = НастройкиОтчета.ПолноеИмя;
	СвойстваВариантаОтчета.ПредставлениеВарианта = ПредставлениеТекущегоВарианта;
	ВариантыОтчетовКлиент.ОбновитьВариантОтчетаИзФайлов(СвойстваВариантаОтчета, УникальныйИдентификатор);

КонецПроцедуры

&НаКлиенте
Процедура ПоделитьсяНастройками(Команда)
	ОписаниеНастроек = Новый Структура;
	ОписаниеНастроек.Вставить("ВариантОтчета", НастройкиОтчета.ВариантСсылка);
	ОписаниеНастроек.Вставить("КлючОбъекта", НастройкиОтчета.ПолноеИмя + "/" + КлючТекущегоВарианта);
	ОписаниеНастроек.Вставить("КлючНастроек", КлючТекущихПользовательскихНастроек);
	ОписаниеНастроек.Вставить("Представление", ПредставлениеТекущихПользовательскихНастроек);
	ОписаниеНастроек.Вставить("Настройки", Отчет.КомпоновщикНастроек.ПользовательскиеНастройки);
	ОписаниеНастроек.Вставить("ВариантМодифицирован", ВариантМодифицирован);

	ВариантыОтчетовКлиент.ПоделитьсяПользовательскимиНастройками(ОписаниеНастроек);
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// Обработчики команд сохранения результата отчета.

&НаКлиенте
Процедура СохранитьОтчет(Команда)

	ТекстПредложения = НСтр("ru = 'Для сохранения результата отчета в файл рекомендуется установить расширение для работы с 1С:Предприятием.'");
	Обработчик = Новый ОписаниеОповещения("СохранитьОтчетЗавершение", ЭтотОбъект);
	ФайловаяСистемаКлиент.ПодключитьРасширениеДляРаботыСФайлами(Обработчик, ТекстПредложения);

КонецПроцедуры

&НаКлиенте
Процедура СохранитьСнимокОтчета(Команда)

	Если НастройкиОтчета.СвойстваРезультата.КомпоновщикНастроек = Неопределено Тогда
		ТекстПредупреждения = НСтр("ru = 'Перед сохранением снимка необходимо сформировать отчет.'");
		ПоказатьПредупреждение(, ТекстПредупреждения);
		Возврат;
	КонецЕсли;

	СохранитьСнимокОтчетаПользователя();

КонецПроцедуры

&НаКлиенте
Процедура СнимкиОтчетов(Команда)

	ОткрытьФорму("РегистрСведений.СнимкиОтчетов.ФормаСписка", Новый Структура("Пользователь",
		ПользователиКлиент.ТекущийПользователь()));

КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// Обработчики команд контекстного меню табличного документа - результат отчета.

&НаКлиенте
Процедура СгруппироватьПоВыбранномуПолю(Команда)

	ВариантыОтчетовСлужебныйКлиент.СгруппироватьПоВыбранномуПолю(ЭтотОбъект, Команда);

КонецПроцедуры

&НаКлиенте
Процедура ВставитьПолеСлева(Команда)

	ВариантыОтчетовСлужебныйКлиент.ВставитьПолеСлева(ЭтотОбъект, Команда);

КонецПроцедуры

&НаКлиенте
Процедура ВставитьПолеСправа(Команда)

	ВариантыОтчетовСлужебныйКлиент.ВставитьПолеСправа(ЭтотОбъект, Команда);

КонецПроцедуры

&НаКлиенте
Процедура ВставитьГруппировкуВыше(Команда)

	ВариантыОтчетовСлужебныйКлиент.ВставитьГруппировкуВыше(ЭтотОбъект, Команда);

КонецПроцедуры

&НаКлиенте
Процедура ВставитьГруппировкуНиже(Команда)

	ВариантыОтчетовСлужебныйКлиент.ВставитьГруппировкуНиже(ЭтотОбъект, Команда);

КонецПроцедуры

&НаКлиенте
Процедура ПереместитьПолеВлево(Команда)

	ВариантыОтчетовСлужебныйКлиент.ПереместитьПолеВлево(ЭтотОбъект, Команда);

КонецПроцедуры

&НаКлиенте
Процедура ПереместитьПолеВправо(Команда)

	ВариантыОтчетовСлужебныйКлиент.ПереместитьПолеВправо(ЭтотОбъект, Команда);

КонецПроцедуры

&НаКлиенте
Процедура ПереместитьПолеВыше(Команда)

	ВариантыОтчетовСлужебныйКлиент.ПереместитьПолеВыше(ЭтотОбъект, Команда);

КонецПроцедуры

&НаКлиенте
Процедура ПереместитьПолеНиже(Команда)

	ВариантыОтчетовСлужебныйКлиент.ПереместитьПолеНиже(ЭтотОбъект, Команда);

КонецПроцедуры

&НаКлиенте
Процедура СкрытьПоле(Команда)

	ВариантыОтчетовСлужебныйКлиент.СкрытьПоле(ЭтотОбъект, Команда);

КонецПроцедуры

&НаКлиенте
Процедура ПереименоватьПоле(Команда)

	ВариантыОтчетовСлужебныйКлиент.ПереименоватьПоле(ЭтотОбъект, Команда);

КонецПроцедуры

&НаКлиенте
Процедура СнятьФильтр(Команда)

	ВариантыОтчетовСлужебныйКлиент.СнятьФильтр(ЭтотОбъект, СвойстваЗаголовка());

КонецПроцедуры

&НаКлиенте
Процедура Фильтровать(Команда)

	СвойстваРезультата = НастройкиОтчета.СвойстваРезультата; // см. ВариантыОтчетовСлужебный.СвойстваРезультатаОтчета
	СвойстваЗаголовка = СвойстваРезультата.Заголовки[ИмяТекущейОбластиЯчеек()];
	ВариантыОтчетовСлужебныйКлиент.ПоказатьРасширеннуюНастройкуФильтра(ЭтотОбъект, СвойстваЗаголовка);

КонецПроцедуры

&НаКлиенте
Процедура СортироватьПоВозрастанию(Команда)

	ВариантыОтчетовСлужебныйКлиент.Сортировать(ЭтотОбъект, Команда);

КонецПроцедуры

&НаКлиенте
Процедура СортироватьПоУбыванию(Команда)

	ВариантыОтчетовСлужебныйКлиент.Сортировать(ЭтотОбъект, Команда);

КонецПроцедуры

&НаКлиенте
Процедура ОчиститьОформление(Команда)

	ВариантыОтчетовСлужебныйКлиент.ОчиститьОформление(ЭтотОбъект, СвойстваЗаголовка());

КонецПроцедуры

&НаКлиенте
Процедура ОформитьОтрицательные(Команда)

	ВариантыОтчетовСлужебныйКлиент.ОформитьКрасным(ЭтотОбъект, Команда);

КонецПроцедуры

&НаКлиенте
Процедура ОформитьПоложительные(Команда)

	ВариантыОтчетовСлужебныйКлиент.ОформитьЗеленым(ЭтотОбъект, Команда);

КонецПроцедуры

&НаКлиенте
Процедура УстановитьВысотуСтроки(Команда)

	ВариантыОтчетовСлужебныйКлиент.УстановитьВысотуСтроки(ЭтотОбъект, Команда);

КонецПроцедуры

&НаКлиенте
Процедура УстановитьШиринуКолонки(Команда)

	ВариантыОтчетовСлужебныйКлиент.УстановитьШиринуКолонки(ЭтотОбъект, Команда);

КонецПроцедуры

&НаКлиенте
Процедура ОформитьЕще(Команда)

	ВариантыОтчетовСлужебныйКлиент.ОформитьЕще(ЭтотОбъект, Команда);

КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// Обработчики команд расчета показателей.

&НаКлиенте
Процедура ВыбратьПоказательНажатие(Элемент)

	Меню = МенюВидовПоказателей(Элементы.КомандыВидовПоказателей);
	ПоказатьВыборИзМеню(Новый ОписаниеОповещения("ПослеВыбораПоказателя", ЭтотОбъект), Меню, Элемент);

КонецПроцедуры

&НаКлиенте
Процедура РассчитатьСумму(Команда)
	РассчитатьПоказатели(Команда.Имя);
КонецПроцедуры

&НаКлиенте
Процедура РассчитатьКоличество(Команда)
	РассчитатьПоказатели(Команда.Имя);
КонецПроцедуры

&НаКлиенте
Процедура РассчитатьСреднее(Команда)
	РассчитатьПоказатели(Команда.Имя);
КонецПроцедуры

&НаКлиенте
Процедура РассчитатьМинимум(Команда)
	РассчитатьПоказатели(Команда.Имя);
КонецПроцедуры

&НаКлиенте
Процедура РассчитатьМаксимум(Команда)
	РассчитатьПоказатели(Команда.Имя);
КонецПроцедуры

&НаКлиенте
Процедура РассчитатьВсеПоказатели(Команда)
	РазвернутьОбластьПоказателей = Не Элементы.РассчитатьВсеПоказатели.Пометка;
	ОбщегоНазначенияСлужебныйКлиент.УстановитьВидимостьПанелиПоказателей(Элементы, РазвернутьОбластьПоказателей);
КонецПроцедуры

&НаКлиенте
Процедура СвернутьПоказатели(Команда)
	ОбщегоНазначенияСлужебныйКлиент.УстановитьВидимостьПанелиПоказателей(Элементы);
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// Подключаемые

// Параметры:
//  Команда - КомандаФормы
//
&НаКлиенте
Процедура Подключаемый_Команда(Команда)

	ПрефиксИмени = ОтчетыКлиентСервер.ПрефиксИмениКомандыСПредварительнымСохранениемВариантаОтчета();
	Если СтрНачинаетсяС(Команда.Имя, ПрефиксИмени) И ТребуетсяСохранитьВариант() Тогда
		СохранитьНовыйИлиСуществующийВариантОтчетаИПродолжить(Команда);
		Возврат;
	КонецЕсли;

	ПостояннаяКоманда = ПостоянныеКоманды.НайтиПоЗначению(Команда.Имя);
	Если ПостояннаяКоманда <> Неопределено И ЗначениеЗаполнено(ПостояннаяКоманда.Представление) Тогда
		МассивПодстрок = СтрРазделить(ПостояннаяКоманда.Представление, ".");
		КлиентскийМодуль = ОбщегоНазначенияКлиент.ОбщийМодуль(МассивПодстрок[0]);
		Обработчик = Новый ОписаниеОповещения(МассивПодстрок[1], КлиентскийМодуль, Команда);
		ВыполнитьОбработкуОповещения(Обработчик, ЭтотОбъект);
	Иначе
		ИнтеграцияПодсистемБСПКлиент.ПриОбработкеКоманды(ЭтотОбъект, Команда, Ложь);
		ОтчетыКлиентПереопределяемый.ОбработчикКоманды(ЭтотОбъект, Команда, Ложь);
	КонецЕсли;
КонецПроцедуры

// Параметры:
//  Команда - КомандаФормы
//
&НаКлиенте
Процедура Подключаемый_ЗагрузитьВариантОтчета(Команда)
	Найденные = ДобавленныеВарианты.НайтиСтроки(Новый Структура("ИмяКоманды", Команда.Имя));
	Если Найденные.Количество() = 0 Тогда
		ПоказатьПредупреждение(, НСтр("ru = 'Вариант отчета не существует.'"));
		Возврат;
	КонецЕсли;

	ВариантФормы = Найденные[0];
	НастройкиОтчета.ФормаНастроекРасширенныйРежим = 0;

	ЗагрузитьВариант(ВариантФормы.КлючВарианта);

	КлючУникальности = ОтчетыКлиентСервер.КлючУникальности(НастройкиОтчета.ПолноеИмя, ВариантФормы.КлючВарианта);

	Если Элементы.ФормироватьСразу.Пометка Тогда
		ПодключитьОбработчикОжидания("Сформировать", 0.1, Истина);
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура Подключаемый_ПоказатьУровеньГруппировок(Команда)

	УровеньГруппировкиСтрокой = СтрЗаменить(Команда.Имя, Элементы.ПоказатьУровеньГруппировок.Имя, "");

	ОписаниеЧисла = Новый ОписаниеТипов("Число");
	УровеньГруппировки = ОписаниеЧисла.ПривестиЗначение(УровеньГруппировкиСтрокой);

	ПоказатьВыбранныйУровеньГруппировок(УровеньГруппировки);

КонецПроцедуры

// Параметры:
//  Команда - КомандаФормы
//
&НаКлиенте
Процедура Подключаемый_ПерейтиМеждуИзменениямиНастроек(Команда)

	ПредставлениеПорядка = СтрЗаменить(Команда.Имя, ПрефиксИмениКомандыПереходаМеждуИзменениямиНастроек(), "");
	ОписаниеЧисла = Новый ОписаниеТипов("Число");
	Порядок = ОписаниеЧисла.ПривестиЗначение(ПредставлениеПорядка);

	НайденныеЗаписи = СтекНастроек.НайтиСтроки(Новый Структура("Порядок", Порядок));
	ТекущиеНастройкиСтека = НайденныеЗаписи[0];

	Результат = ВариантыОтчетовСлужебныйКлиент.РезультатКонтекстнойНастройки(
		Отчет.КомпоновщикНастроек, ТекущиеНастройкиСтека.Действие, УникальныйИдентификатор);

	Результат.Вставить("НастройкиКД", ТекущиеНастройкиСтека.Настройки);
	Результат.Удалить("КомпоновщикНастроекКД");

	УточнитьПризнакАвтоформированияОтчета(Результат);

	ВариантыОтчетовСлужебныйКлиент.СброситьПометкиСтекаНастроек(СтекНастроек);
	ТекущиеНастройкиСтека.Пометка = Истина;


КонецПроцедуры

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

////////////////////////////////////////////////////////////////////////////////
// Клиент

&НаКлиенте
Процедура ОпределитьПоведениеНаНачальнойСтранице()

	ОкноНачальнойСтраницы = Неопределено;

	ОкнаПрограммы = ПолучитьОкна();
	
	Если ОкнаПрограммы = Неопределено Тогда
		Возврат;
	КонецЕсли;

	Для Каждого ОкноПрограммы Из ОкнаПрограммы Цикл

		Если ОкноПрограммы.НачальнаяСтраница Тогда

			ОкноНачальнойСтраницы = ОкноПрограммы;
			Прервать;

		КонецЕсли;

	КонецЦикла;

	Если ОкноНачальнойСтраницы = Неопределено Тогда
		Возврат;
	КонецЕсли;

	ЭтоФормаНачальнойСтраницы = Ложь;
	Для Каждого ФормаНачальнойСтраницы Из ОкноНачальнойСтраницы.Содержимое Цикл
		Если ФормаНачальнойСтраницы.ИмяФормы = ИмяФормы И ФормаНачальнойСтраницы.КлючУникальности = КлючУникальности Тогда
			ЭтоФормаНачальнойСтраницы = Истина;
			Прервать;
		КонецЕсли;
	КонецЦикла;

	Если Не ЭтоФормаНачальнойСтраницы Тогда
		Возврат;
	КонецЕсли;

	ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(Элементы, "ГруппаСохранениеВыборВариантаОтчета",
		"Видимость", Ложь);
	ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(Элементы, "Найти", "Видимость", Ложь);
	ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(Элементы, "ГруппаВывод", "Видимость", Ложь);

КонецПроцедуры

&НаКлиенте
Процедура ОбновитьЭлементыФормыНастроек(ПараметрыОбновления)
	ОбновитьЭлементыФормыНастроекНаСервере(ПараметрыОбновления);

	Если ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ПараметрыОбновления, "Переформировать", Ложь) Тогда
		ОчиститьСообщения();
		Сформировать();
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ОбновитьЭлементыФормыНастроекОтложенно()

	ОбновитьЭлементыФормыНастроек(РезультатНастройки);

КонецПроцедуры

#Область ФормированиеСОтправкойПоПочте

&НаКлиенте
Процедура СформироватьПередОтправкойПоПочте(Ответ, ДополнительныеПараметры) Экспорт
	Если Ответ = КодВозвратаДиалога.Да Тогда
		Обработчик = Новый ОписаниеОповещения("ОтправитьПоПочтеПослеФормирования", ЭтотОбъект);
		ОтчетыКлиент.СформироватьОтчет(ЭтотОбъект, Обработчик);
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ОтправитьПоПочтеПослеФормирования(ТабличныйДокументСформирован, ДополнительныеПараметры) Экспорт
	Если ТабличныйДокументСформирован Тогда
		ПоказатьДиалогОтправкиПоПочте();
	КонецЕсли;
КонецПроцедуры

#КонецОбласти

#Область Формирование

&НаКлиенте
Асинх Процедура Сформировать()

	Если ЗначениеЗаполнено(ПутьКФайлуВнешнегоОтчетаНаКлиенте) И Не ЗначениеЗаполнено(АдресДвоичныхДанныхВнешнегоОтчета) Тогда
		Результат = Ждать ПоместитьФайлНаСерверАсинх(,,, ПутьКФайлуВнешнегоОтчетаНаКлиенте, УникальныйИдентификатор); // ОписаниеПомещенногоФайла
		Если ТипЗнч(Результат) = Тип("ОписаниеПомещенногоФайла") И Не Результат.ПомещениеФайлаОтменено Тогда
			АдресДвоичныхДанныхВнешнегоОтчета = Результат.Адрес;
		КонецЕсли;
	КонецЕсли;

	СформироватьОтчет();

КонецПроцедуры

&НаКлиенте
Процедура СформироватьОтчет()

	НачатьЗамер();
	ПараметрыФормирования = Новый Структура("ВремяНачалаФормирования", ТекущаяУниверсальнаяДатаВМиллисекундах());
	Результат = РезультатФормированияОтчета(ФормированиеПриОткрытии, 
		НастройкиОтчета.Внешний Или НастройкиОтчета.Безопасный, Ложь);
	Если Результат = Неопределено Тогда
		Возврат;
	КонецЕсли;

	Контекст = Новый Структура;
	Контекст.Вставить("Результат", Результат);
	Контекст.Вставить("ПараметрыФормирования", ПараметрыФормирования);
	Контекст.Вставить("НастройкаОтказаОтПредупреждения", Неопределено);

	Если Результат.Свойство("ИмяПараметраХраненияОтказаОтПредупреждения") Тогда
		Предупредить = Истина;
		ПредлагатьБольшеНеПредупреждать = Истина;

		Если ЗначениеЗаполнено(Результат.ИмяПараметраХраненияОтказаОтПредупреждения) Тогда
			ПараметрКомпоновки = Новый ПараметрКомпоновкиДанных(Результат.ИмяПараметраХраненияОтказаОтПредупреждения);
			Для Каждого Настройка Из Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы Цикл
				Если Настройка.Параметр = ПараметрКомпоновки Тогда
					Контекст.НастройкаОтказаОтПредупреждения = Настройка;
					Прервать;
				КонецЕсли;
			КонецЦикла;
			Если Контекст.НастройкаОтказаОтПредупреждения = Неопределено Тогда
				ПредлагатьБольшеНеПредупреждать = Ложь;
			ИначеЕсли Контекст.НастройкаОтказаОтПредупреждения.Значение = Истина Тогда
				Предупредить = Ложь;
			КонецЕсли;
		Иначе
			ПредлагатьБольшеНеПредупреждать = Ложь;
		КонецЕсли;

		Если Предупредить Тогда
			Кнопки = Новый СписокЗначений;
			Кнопки.Добавить("Продолжить", НСтр("ru = 'Продолжить'"));
			Кнопки.Добавить("Отмена", НСтр("ru = 'Отмена'"));
			ПараметрыВопроса = СтандартныеПодсистемыКлиент.ПараметрыВопросаПользователю();
			ПараметрыВопроса.КнопкаПоУмолчанию = "Отмена";
			ПараметрыВопроса.Заголовок = Заголовок;
			ПараметрыВопроса.ПредлагатьБольшеНеЗадаватьЭтотВопрос = ПредлагатьБольшеНеПредупреждать;
			СтандартныеПодсистемыКлиент.ПоказатьВопросПользователю(
				Новый ОписаниеОповещения("СформироватьПослеПредупреждения", ЭтотОбъект, Контекст),
				Результат.ТекстПредупреждения, Кнопки, ПараметрыВопроса);
			Возврат;
		КонецЕсли;
	КонецЕсли;

	СформироватьПослеПредупреждения(Null, Контекст);

КонецПроцедуры

&НаКлиенте
Процедура СформироватьПослеПредупреждения(Ответ, Контекст) Экспорт

	ПараметрыФормирования = Контекст.ПараметрыФормирования;

	Если Ответ = Null Тогда
		Результат = Контекст.Результат;

	ИначеЕсли ТипЗнч(Ответ) = Тип("Структура") Тогда
		Если Ответ.БольшеНеЗадаватьЭтотВопрос И Контекст.НастройкаОтказаОтПредупреждения <> Неопределено Тогда
			Контекст.НастройкаОтказаОтПредупреждения.Значение = Истина;
		КонецЕсли;
		Если Ответ.Значение = "Продолжить" Тогда
			НачатьЗамер();
			ПараметрыФормирования.ВремяНачалаФормирования = ТекущаяУниверсальнаяДатаВМиллисекундах();
			Результат = РезультатФормированияОтчета(ФормированиеПриОткрытии, НастройкиОтчета.Внешний
				Или НастройкиОтчета.Безопасный, Истина);
		Иначе
			Возврат;
		КонецЕсли;
	Иначе
		Возврат;
	КонецЕсли;

	Если Результат = Неопределено Тогда
		Возврат;
	КонецЕсли;

	ПараметрыФормирования.Вставить("ЗагрузитьРезультат", Ложь);
	ПараметрыФормирования.Вставить("ИдентификаторЗадания", Результат.ИдентификаторЗадания);

	Если Результат.Статус <> "Выполняется" Тогда
		ПослеФормирования(Результат, ПараметрыФормирования);
		Возврат;
	КонецЕсли;

	ПараметрыФормирования.ЗагрузитьРезультат = Истина;

	Обработчик = Новый ОписаниеОповещения("ПослеФормирования", ЭтотОбъект, ПараметрыФормирования);
	ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);
	ПараметрыОжидания.ВыводитьОкноОжидания = Ложь;

	ДлительныеОперацииКлиент.ОжидатьЗавершение(Результат, Обработчик, ПараметрыОжидания);
КонецПроцедуры

&НаКлиенте
Процедура НачатьЗамер()

	ВыполнятьЗамеры = НастройкиОтчета.ВыполнятьЗамеры И ЗначениеЗаполнено(НастройкиОтчета.КлючЗамеров);
	Если ВыполнятьЗамеры Тогда
		МодульОценкаПроизводительностиКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("ОценкаПроизводительностиКлиент");
		ИдентификаторЗамера = МодульОценкаПроизводительностиКлиент.ЗамерВремени(
			НастройкиОтчета.КлючЗамеров + ".Формирование", Ложь, Ложь);
		Комментарий = Новый Соответствие;
		Комментарий.Вставить("Непосредственно", Непосредственно);
		МодульОценкаПроизводительностиКлиент.УстановитьКомментарийЗамера(ИдентификаторЗамера, Комментарий);
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура ПослеФормирования(Результат, ПараметрыФормирования) Экспорт

	Если ФоновоеЗаданиеИдентификатор <> ПараметрыФормирования.ИдентификаторЗадания Или Не Открыта() Тогда
		Возврат;
	КонецЕсли;
	
	ФоновоеЗаданиеИдентификатор = Неопределено;
	
	Если Результат = Неопределено Тогда

		ПоказатьОшибкиФормирования(НСтр("ru = 'Формирование отчета прервано администратором'"));
		ПоказатьОповещениеПользователя(НСтр("ru = 'Отчет не сформирован'"),
			?(Окно <> Неопределено, Окно.ПолучитьНавигационнуюСсылку(), Неопределено), Заголовок);

	ИначеЕсли Результат.Статус = "Выполнено" Тогда

		Если ПараметрыФормирования.ЗагрузитьРезультат Тогда
			ЗагрузитьРезультатФормированияОтчета();
		КонецЕсли;

		НастройкиОтчета.СвойстваРезультата.ВремяФормирования = (ТекущаяУниверсальнаяДатаВМиллисекундах()
			- ПараметрыФормирования.ВремяНачалаФормирования) / 1000;
			
		ПоказатьОповещениеПользователя(НСтр("ru = 'Отчет сформирован'"),
			?(Окно <> Неопределено, Окно.ПолучитьНавигационнуюСсылку(), Неопределено), Заголовок);

	ИначеЕсли Результат.Статус = "Ошибка" Тогда

		ПоказатьОшибкиФормирования(Результат.КраткоеПредставлениеОшибки);
		ПоказатьОповещениеПользователя(НСтр("ru = 'Отчет не сформирован'"),
			?(Окно <> Неопределено, Окно.ПолучитьНавигационнуюСсылку(), Неопределено), Заголовок);
	КонецЕсли;

	ФормированиеПриОткрытии = Ложь;

	ВыполнятьЗамеры = НастройкиОтчета.ВыполнятьЗамеры И ЗначениеЗаполнено(НастройкиОтчета.КлючЗамеров);
	Если ВыполнятьЗамеры Тогда
		МодульОценкаПроизводительностиКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("ОценкаПроизводительностиКлиент");
		МодульОценкаПроизводительностиКлиент.ЗавершитьЗамерВремени(ИдентификаторЗамера);
	КонецЕсли;

	ОтчетСформирован = ?(Результат = Неопределено, Ложь, Результат.Статус = "Выполнено");

	ИнтеграцияПодсистемБСПКлиент.ПослеФормирования(ЭтотОбъект, ОтчетСформирован);
	ОтчетыКлиентПереопределяемый.ПослеФормирования(ЭтотОбъект, ОтчетСформирован);

	СброситьТекущуюОбласть();
	ПоказатьВыбранныйУровеньГруппировок();

	Обработчик = ОбработчикПослеФормированияНаКлиенте;
	Если ТипЗнч(Обработчик) = Тип("ОписаниеОповещения") Тогда
		ВыполнитьОбработкуОповещения(Обработчик, ОтчетСформирован);
		ОбработчикПослеФормированияНаКлиенте = Неопределено;
	КонецЕсли;

КонецПроцедуры

&НаСервере
Функция РезультатФормированияОтчета(Знач ФормированиеПриОткрытии, Непосредственно, ПослеПредупреждения)

	Если ЗначениеЗаполнено(ФоновоеЗаданиеИдентификатор) Тогда
		ДлительныеОперации.ОтменитьВыполнениеЗадания(ФоновоеЗаданиеИдентификатор);
		ФоновоеЗаданиеИдентификатор = Неопределено;
	КонецЕсли;

	Если Не ПроверитьЗаполнение() Тогда
		Если ФормированиеПриОткрытии Тогда
			ТекстОшибки = "";
			Сообщения = ПолучитьСообщенияПользователю(Истина);
			Для Каждого Сообщение Из Сообщения Цикл
				ТекстОшибки = ТекстОшибки + ?(ТекстОшибки = "", "", ";" + Символы.ПС + Символы.ПС) + Сообщение.Текст;
			КонецЦикла;
			ПоказатьОшибкиФормирования(ТекстОшибки);
		КонецЕсли;
		Возврат Неопределено;
	КонецЕсли;

	Если НастройкиОтчета.События.ПередФормированиемОтчета И Не ПослеПредупреждения Тогда
		ПараметрыВопроса = Новый Структура;
		ПараметрыВопроса.Вставить("ТекстПредупреждения", "");
		ПараметрыВопроса.Вставить("ИмяПараметраХраненияОтказаОтПредупреждения", "");
		ОтчетОбъект = РеквизитФормыВЗначение("Отчет");
		ОтчетОбъект.ПередФормированиемОтчета(ЭтотОбъект, ПараметрыВопроса);
		Если ЗначениеЗаполнено(ПараметрыВопроса.ТекстПредупреждения) Тогда
			Возврат ПараметрыВопроса;
		КонецЕсли;
	КонецЕсли;

	ИмяОтчета = СтрРазделить(НастройкиОтчета.ПолноеИмя, ".")[1];
	ПараметрыФормирования = ПараметрыФормированияОтчета(ИмяОтчета, Непосредственно);
	ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне(УникальныйИдентификатор);
	ПараметрыВыполнения.НаименованиеФоновогоЗадания = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = 'Выполнение отчета: %1'"), ИмяОтчета);
	ПараметрыВыполнения.ЗапуститьНеВФоне = Непосредственно;

	Результат = ДлительныеОперации.ВыполнитьВФоне("ВариантыОтчетов.СформироватьОтчетВФоне", ПараметрыФормирования,
		ПараметрыВыполнения);

	ФоновоеЗаданиеИдентификатор = Результат.ИдентификаторЗадания;
	ФоновоеЗаданиеАдресХранилища = Результат.АдресРезультата;

	Если Результат.Статус <> "Выполняется" Тогда
		ЗагрузитьРезультатФормированияОтчета();
	Иначе
		ОтчетыКлиентСервер.ОтобразитьСостояниеОтчета(
			ЭтотОбъект, НСтр("ru = 'Отчет формируется...'"), БиблиотекаКартинок.ДлительнаяОперация48);
	КонецЕсли;
	Возврат Результат;

КонецФункции

&НаСервере
Функция ПараметрыФормированияОтчета(ИмяОтчета, Непосредственно)

	ДополнительныеСвойства = Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.ДополнительныеСвойства;
	ДополнительныеСвойства.Вставить("ВариантМодифицирован", ВариантМодифицирован);
	ДополнительныеСвойства.Вставить("ПользовательскиеНастройкиМодифицированы", ПользовательскиеНастройкиМодифицированы);

	ПараметрыФормированияОтчета = ВариантыОтчетов.ПараметрыФормированияОтчета();
	ПараметрыФормированияОтчета.СсылкаОтчета = НастройкиОтчета.ОтчетСсылка;
	ПараметрыФормированияОтчета.СсылкаВарианта = НастройкиОтчета.ВариантСсылка;
	ПараметрыФормированияОтчета.КлючВарианта = КлючТекущегоВарианта;
	ПараметрыФормированияОтчета.КлючСхемы = НастройкиОтчета.КлючСхемы;
	ПараметрыФормированияОтчета.ИспользуемыеТаблицы = НастройкиОтчета.ИспользуемыеТаблицы;
	ПараметрыФормированияОтчета.ДвоичныеДанныеВнешнегоОтчета = ?(ЗначениеЗаполнено(АдресДвоичныхДанныхВнешнегоОтчета),
		ПолучитьИзВременногоХранилища(АдресДвоичныхДанныхВнешнегоОтчета), Неопределено);
	ПараметрыФормированияОтчета.ПараметрыИзменены = ПараметрыИзменены;
	ПараметрыФормированияОтчета.СхемаМодифицирована = НастройкиОтчета.СхемаМодифицирована;
	ПараметрыФормированияОтчета.НастройкиКД = Отчет.КомпоновщикНастроек.Настройки;
	ПараметрыФормированияОтчета.ФиксированныеНастройкиКД = Отчет.КомпоновщикНастроек.ФиксированныеНастройки;
	ПараметрыФормированияОтчета.ПользовательскиеНастройкиКД = Отчет.КомпоновщикНастроек.ПользовательскиеНастройки;
	ЗаполнитьЗначенияСвойств(ПараметрыФормированияОтчета, ПараметрыЗамеровФормированияОтчета(ИмяОтчета));

	Если Непосредственно Тогда
		Если НастройкиОтчета.СхемаМодифицирована Тогда
			ПараметрыФормированияОтчета.АдресСхемы = НастройкиОтчета.АдресСхемы;
		КонецЕсли;
		ПараметрыФормированияОтчета.Объект = РеквизитФормыВЗначение("Отчет");
		ПараметрыФормированияОтчета.ПолноеИмя = НастройкиОтчета.ПолноеИмя;
	Иначе
		Если НастройкиОтчета.СхемаМодифицирована Тогда
			ПараметрыФормированияОтчета.СхемаКД = ПолучитьИзВременногоХранилища(НастройкиОтчета.АдресСхемы);
		КонецЕсли;
	КонецЕсли;

	Возврат ПараметрыФормированияОтчета;

КонецФункции

&НаСервере
Функция ПараметрыЗамеровФормированияОтчета(ИмяОтчета)
	ПараметрыЗамеров = Новый Структура("ИмяКлючевойОперации, КомментарийКлючевойОперации");

	Если Не НастройкиОтчета.ВыполнятьЗамеры Или Не ЗначениеЗаполнено(НастройкиОтчета.КлючЗамеров) Тогда
		Возврат ПараметрыЗамеров;
	КонецЕсли;

	КомментарийКлючевойОперации = Новый Соответствие;
	КомментарийКлючевойОперации.Вставить("ИмяОтчета", ИмяОтчета);
	КомментарийКлючевойОперации.Вставить("КлючПредопределенногоВарианта", НастройкиОтчета.КлючПредопределенногоВарианта);
	КомментарийКлючевойОперации.Вставить("Внешний", Число(НастройкиОтчета.Внешний));
	КомментарийКлючевойОперации.Вставить("Пользовательский", Число(НастройкиОтчета.Пользовательский));
	КомментарийКлючевойОперации.Вставить("Расшифровка", Число(РежимРасшифровки));
	КомментарийКлючевойОперации.Вставить("Модифицирован", Число(ВариантМодифицирован));

	ПараметрыЗамеров.ИмяКлючевойОперации = НастройкиОтчета.КлючЗамеров + ".Формирование";
	ПараметрыЗамеров.КомментарийКлючевойОперации = КомментарийКлючевойОперации;

	Возврат ПараметрыЗамеров;
КонецФункции

&НаСервере
Процедура ЗагрузитьРезультатФормированияОтчета()
	Если Не ЭтоАдресВременногоХранилища(ФоновоеЗаданиеАдресХранилища) Тогда
		ПоказатьОшибкиФормирования(НСтр("ru = 'Не удалось сформировать отчет'"));
		Возврат;
	КонецЕсли;

	Результат = ПолучитьИзВременногоХранилища(ФоновоеЗаданиеАдресХранилища);

	УдалитьИзВременногоХранилища(ФоновоеЗаданиеАдресХранилища);
	ФоновоеЗаданиеАдресХранилища = Неопределено;

	Если Результат = Неопределено Тогда
		ПоказатьОшибкиФормирования(НСтр("ru = 'Не удалось сформировать отчет (пустой результат)'"));
		Возврат;
	КонецЕсли;

	Успех = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Результат, "Успех");
	Если Успех <> Истина Тогда
		ПоказатьОшибкиФормирования(Результат.ТекстОшибки);
		Возврат;
	КонецЕсли;

	ДанныеЕщеОбновляются = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Результат, "ДанныеЕщеОбновляются", Ложь);
	Если ДанныеЕщеОбновляются Тогда
		ОбщегоНазначения.СообщитьПользователю(ВариантыОтчетов.СообщениеДанныеЕщеОбновляются());
	КонецЕсли;

	ОтчетыКлиентСервер.ОтобразитьСостояниеОтчета(ЭтотОбъект);

	ЗаполнитьЗначенияСвойств(НастройкиОтчета.Печать, ОтчетТабличныйДокумент); // Сохранение настроек печати.
	ОтчетТабличныйДокумент = Результат.ТабличныйДокумент;
	ЗаполнитьЗначенияСвойств(ОтчетТабличныйДокумент, НастройкиОтчета.Печать); // Восстановление.
	ОтчетСформирован = Истина;

	Если ЗначениеЗаполнено(ОтчетДанныеРасшифровки) И ЭтоАдресВременногоХранилища(ОтчетДанныеРасшифровки) Тогда
		УдалитьИзВременногоХранилища(ОтчетДанныеРасшифровки);
	КонецЕсли;
	ОтчетДанныеРасшифровки = ПоместитьВоВременноеХранилище(Результат.Расшифровка, УникальныйИдентификатор);

	ВариантыОтчетовСлужебный.ИнициализироватьЗаголовкиОтчета(ЭтотОбъект);
	ИнициализироватьМенюУровнейГруппировок();

	Если Не Результат.ВариантМодифицирован И Не Результат.ПользовательскиеНастройкиМодифицированы Тогда
		Возврат;
	КонецЕсли;

	Результат.Вставить("ИмяСобытия", "ПослеФормирования");
	Результат.Вставить("Непосредственно", Ложь);

	ОбновитьЭлементыФормыНастроекНаСервере(Результат);
КонецПроцедуры

#КонецОбласти

&НаКлиенте
Процедура ПоказатьДиалогОтправкиПоПочте()
	Вложение = Новый Структура;
	Вложение.Вставить("АдресВоВременномХранилище", ПоместитьВоВременноеХранилище(ОтчетТабличныйДокумент,
		УникальныйИдентификатор));
	Вложение.Вставить("Представление", ОтчетНаименованиеТекущегоВарианта);

	СписокВложений = ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(Вложение);

	Если ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.РаботаСПочтовымиСообщениями") Тогда
		МодульРаботаСПочтовымиСообщениямиКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль(
			"РаботаСПочтовымиСообщениямиКлиент");
		ПараметрыОтправки = МодульРаботаСПочтовымиСообщениямиКлиент.ПараметрыОтправкиПисьма();
		ПараметрыОтправки.Тема = ОтчетНаименованиеТекущегоВарианта;
		ПараметрыОтправки.Вложения = СписокВложений;
		МодульРаботаСПочтовымиСообщениямиКлиент.СоздатьНовоеПисьмо(ПараметрыОтправки);
	КонецЕсли;
КонецПроцедуры

// Параметры:
//  Элемент - ПолеФормы
//  СтандартнаяОбработка - Булево
//
&НаКлиенте
Процедура ПоказатьСписокВыбора(Элемент, СтандартнаяОбработка)
	СтандартнаяОбработка = Ложь;

	Сведения = ОтчетыКлиент.СведенияОЭлементеНастройки(Отчет.КомпоновщикНастроек, Элемент.Имя);
	ОписаниеНастроек = Сведения.Описание;

	ПользовательскиеНастройки = Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы;

	ПараметрыВыбора = ОтчетыКлиентСервер.ПараметрыВыбора(
		Сведения.Настройки, ПользовательскиеНастройки, Сведения.Элемент);

	РасширенноеОписаниеТипов = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(
		Отчет.КомпоновщикНастроек.Настройки.ДополнительныеСвойства, "РасширенноеОписаниеТипов");

	ТипЗначения = Неопределено;
	Если РасширенноеОписаниеТипов <> Неопределено Тогда
		РасширенноеОписаниеТипа = РасширенноеОписаниеТипов[Сведения.Индекс];
		Если РасширенноеОписаниеТипа <> Неопределено Тогда
			ТипЗначения = РасширенноеОписаниеТипа.ОписаниеТиповДляФормы;
		КонецЕсли;
	КонецЕсли;

	Элемент.ДоступныеТипы = ОтчетыКлиент.ТипЗначенияОграниченныйСвязьюПоТипу(
		Сведения.Настройки, ПользовательскиеНастройки, Сведения.Элемент, ОписаниеНастроек, ТипЗначения);

	Если ТипЗнч(Сведения.ЭлементПользовательскойНастройки) = Тип("ЗначениеПараметраНастроекКомпоновкиДанных") Тогда
		ТекущееЗначение = Сведения.ЭлементПользовательскойНастройки.Значение;
	Иначе
		ТекущееЗначение = Сведения.ЭлементПользовательскойНастройки.ПравоеЗначение;
	КонецЕсли;

	ОтмеченныеЗначения = ОтчетыКлиентСервер.ЗначенияСписком(ТекущееЗначение);
	ДоступныеЗначения = ?(ОписаниеНастроек = Неопределено, Неопределено, ОписаниеНастроек.ДоступныеЗначения);

	Условие = ОтчетыКлиентСервер.УсловиеЭлементаНастройки(Сведения.ЭлементПользовательскойНастройки, ОписаниеНастроек);
	ВыборГруппИЭлементов = ОтчетыКлиент.ЗначениеТипаИспользованиеГруппИЭлементов(
		?(ОписаниеНастроек = Неопределено, Неопределено, ОписаниеНастроек.ВыборГруппИЭлементов), Условие);

	ЗначенияДляВыбора = ЗначенияДляВыбора(Элемент.СписокВыбора, Сведения.ЭлементПользовательскойНастройки, 
		Элемент.ДоступныеТипы, ДоступныеЗначения);

	ОграничиватьВыборУказаннымиЗначениями = ДоступныеЗначения <> Неопределено;

	ПараметрыОбработчика = Новый Структура;
	ПараметрыОбработчика.Вставить("ЭлементПользовательскойНастройки", Сведения.ЭлементПользовательскойНастройки);
	ПараметрыОбработчика.Вставить("ОграничиватьВыборУказаннымиЗначениями", ОграничиватьВыборУказаннымиЗначениями);
	ПараметрыОбработчика.Вставить("ИмяЭлемента", Элемент.Имя);

	Обработчик = Новый ОписаниеОповещения("ЗавершитьВыборИзСписка", ЭтотОбъект, ПараметрыОбработчика);

	Если ОтчетыКлиент.ВыборПереопределен(ЭтотОбъект, Обработчик, Сведения.Описание, Элемент.ДоступныеТипы,
		ОтмеченныеЗначения, ПараметрыВыбора) Тогда
		Возврат;
	КонецЕсли;

	Если ОтчетыКлиент.ЭтоВыборОбъектовМетаданных(Элемент.ДоступныеТипы, ОтмеченныеЗначения, Обработчик)
		Или ОтчетыКлиент.ЭтоВыборПользователей(ЭтотОбъект, Элемент, Элемент.ДоступныеТипы, ОтмеченныеЗначения,
			ПараметрыВыбора, Обработчик) Тогда
		Возврат;
	КонецЕсли;

	ПараметрыОткрытия = Новый Структура;
	ПараметрыОткрытия.Вставить("Отмеченные", ОтмеченныеЗначения);
	ПараметрыОткрытия.Вставить("ОписаниеТипов", Элемент.ДоступныеТипы);
	ПараметрыОткрытия.Вставить("ЗначенияДляВыбора", ЗначенияДляВыбора);
	ПараметрыОткрытия.Вставить("ЗначенияДляВыбораЗаполнены", Элемент.СписокВыбора.Количество() > 0);
	ПараметрыОткрытия.Вставить("ОграничиватьВыборУказаннымиЗначениями", ОграничиватьВыборУказаннымиЗначениями);
	ПараметрыОткрытия.Вставить("Представление", Элемент.Заголовок);
	ПараметрыОткрытия.Вставить("ПараметрыВыбора", Новый Массив(ПараметрыВыбора));
	ПараметрыОткрытия.Вставить("ВыборГруппИЭлементов", ВыборГруппИЭлементов);
	ПараметрыОткрытия.Вставить("БыстрыйВыбор", ?(ОписаниеНастроек = Неопределено, Ложь, ОписаниеНастроек.БыстрыйВыбор));

	ОткрытьФорму("ОбщаяФорма.ВводЗначенийСпискомСФлажками", ПараметрыОткрытия, ЭтотОбъект,,,, Обработчик);
КонецПроцедуры

&НаКлиенте
Функция ЗначенияДляВыбора(СписокВыбора, ЭлементНастройки, ДоступныеТипы, ДоступныеЗначения)
	ЗначенияДляВыбора = ОбщегоНазначенияКлиент.СкопироватьРекурсивно(СписокВыбора);
	Если ЭлементНастройки = Неопределено Тогда
		Возврат ЗначенияДляВыбора;
	КонецЕсли;

	ЗначенияДляВыбора.ТипЗначения = ДоступныеТипы;

	ЗначениеОтбора = ОтчетыКлиент.КэшЗначенияОтбора(Отчет.КомпоновщикНастроек, ЭлементНастройки);
	Если ЗначениеОтбора <> Неопределено Тогда
		ОбщегоНазначенияКлиентСервер.ДополнитьСписок(ЗначенияДляВыбора, ЗначениеОтбора);
	КонецЕсли;

	ОтчетыКлиент.ОбновитьПредставленияСписка(ЗначенияДляВыбора, ДоступныеЗначения);

	Возврат ЗначенияДляВыбора;
КонецФункции

// Параметры:
//  Список - СписокЗначений
//         - Массив из СправочникСсылка.Пользователи
//  ПараметрыВыбора - Структура:
//    * ЭлементПользовательскойНастройки - ЭлементОтбораКомпоновкиДанных
//                                       - ЗначениеПараметраНастроекКомпоновкиДанных
//    * ОграничиватьВыборУказаннымиЗначениями - Булево
//    * ИмяЭлемента - Строка
//
&НаКлиенте
Процедура ЗавершитьВыборИзСписка(Список, ПараметрыВыбора) Экспорт
	Если ТипЗнч(Список) = Тип("Массив") Тогда
		ВыбранныеЗначения = Список;

		Список = Новый СписокЗначений;
		Список.ЗагрузитьЗначения(ВыбранныеЗначения);
		Список.ЗаполнитьПометки(Истина);
	ИначеЕсли ТипЗнч(Список) <> Тип("СписокЗначений") Тогда
		Возврат;
	КонецЕсли;

	ВыбранныеЗначения = Новый СписокЗначений;
	Для Каждого ЭлементСписка Из Список Цикл
		Если ЭлементСписка.Пометка Тогда
			ЗаполнитьЗначенияСвойств(ВыбранныеЗначения.Добавить(), ЭлементСписка);
		КонецЕсли;
	КонецЦикла;

	ЭлементПользовательскойНастройки = ПараметрыВыбора.ЭлементПользовательскойНастройки;
	ЭлементПользовательскойНастройки.Использование = Истина;

	Если ТипЗнч(ЭлементПользовательскойНастройки) = Тип("ЗначениеПараметраНастроекКомпоновкиДанных") Тогда
		ЭлементПользовательскойНастройки.Значение = ВыбранныеЗначения;
	Иначе
		ЭлементПользовательскойНастройки.ПравоеЗначение = ВыбранныеЗначения;
	КонецЕсли;

	Если Не ПараметрыВыбора.ОграничиватьВыборУказаннымиЗначениями Тогда
		Элемент = Элементы.Найти(ПараметрыВыбора.ИмяЭлемента);

		Если Элемент <> Неопределено Тогда
			Элемент.СписокВыбора.Очистить();

			Для Каждого ЭлементСписка Из Список Цикл
				ЗаполнитьЗначенияСвойств(Элемент.СписокВыбора.Добавить(), ЭлементСписка);
			КонецЦикла;
		КонецЕсли;
	КонецЕсли;

	ОтчетыКлиент.КэшироватьЗначениеОтбора(Отчет.КомпоновщикНастроек, ЭлементПользовательскойНастройки, Список);

	ОтчетыКлиентСервер.ОповеститьОИзмененииНастроек(ЭтотОбъект);
КонецПроцедуры

&НаКлиенте
Функция ПерейтиПоСсылке(АдресСсылки)
	Если ПустаяСтрока(АдресСсылки) Тогда
		Возврат Ложь;
	КонецЕсли;
	АдресСсылкиВРег = ВРег(АдресСсылки);
	Если СтрНачинаетсяС(АдресСсылкиВРег, ВРег("http://")) Или СтрНачинаетсяС(АдресСсылкиВРег, ВРег("https://"))
		Или СтрНачинаетсяС(АдресСсылкиВРег, ВРег("e1cib/")) Или СтрНачинаетсяС(АдресСсылкиВРег, ВРег("e1c://")) Тогда
		ФайловаяСистемаКлиент.ОткрытьНавигационнуюСсылку(АдресСсылки);
		Возврат Истина;
	КонецЕсли;
	Возврат Ложь;
КонецФункции

&НаКлиенте
Процедура ЗагрузитьСхемуПослеПомещенияФайла(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт
	Если ВыбранныеФайлы = Неопределено Тогда
		Возврат;
	КонецЕсли;

	ДвоичныеДанные = ПолучитьИзВременногоХранилища(ВыбранныеФайлы.Хранение);

	ДополнительныеСвойства = Отчет.КомпоновщикНастроек.Настройки.ДополнительныеСвойства;
	ДополнительныеСвойства.Очистить();
	ДополнительныеСвойства.Вставить("СхемаКомпоновкиДанных", ДвоичныеДанные);
	ДополнительныеСвойства.Вставить("ОтчетИнициализирован", Ложь);

	ПараметрыЗаполнения = Новый Структура;
	ПараметрыЗаполнения.Вставить("ПользовательскиеНастройкиМодифицированы", Истина);
	ПараметрыЗаполнения.Вставить("КомпоновщикНастроекКД", Отчет.КомпоновщикНастроек);

	ОбновитьЭлементыФормыНастроек(ПараметрыЗаполнения);
КонецПроцедуры

&НаКлиенте
Процедура ПрименитьПереданныеНастройки(ОписаниеНастроек)
	Если ВариантМодифицирован Тогда
		ПоказатьПредупреждение(, НСтр("ru = 'Вариант отчета был изменен.
			|Сохраните изменения перед применением настроек.'"));
		Возврат;
	КонецЕсли;

	УстановитьТекущиеПользовательскиеНастройки(ОписаниеНастроек.КлючНастроек);
	ПредставлениеТекущихПользовательскихНастроек = ОписаниеНастроек.Представление;

	Отчет.КомпоновщикНастроек.ЗагрузитьПользовательскиеНастройки(ОписаниеНастроек.Настройки);
	Сформировать();
КонецПроцедуры

#Область РасчетПоказателей

// Параметры:
//  Родитель - ГруппаФормы
//  Меню - Неопределено
//       - СписокЗначений
// 
// Возвращаемое значение:
//  - Неопределено
//  - СписокЗначений
//
&НаКлиенте
Функция МенюВидовПоказателей(Родитель, Меню = Неопределено)

	Если Меню = Неопределено Тогда
		Меню = Новый СписокЗначений;
	КонецЕсли;

	ЭлементыМеню = Родитель.ПодчиненныеЭлементы; // ЭлементыФормы

	Для Каждого Элемент Из ЭлементыМеню Цикл

		Если ТипЗнч(Элемент) <> Тип("ГруппаФормы") Тогда
			Меню.Добавить(Элемент.Имя, Элемент.Заголовок, ОсновнойПоказатель = Элемент.Имя);
		Иначе
			МенюВидовПоказателей(Элемент, Меню);
		КонецЕсли;

	КонецЦикла;

	ЭлементМеню = Меню.НайтиПоЗначению(Элементы.РассчитатьВсеПоказатели.Имя);

	Если ЭлементМеню <> Неопределено Тогда
		ЭлементМеню.Пометка = РазвернутьОбластьПоказателей;
	КонецЕсли;

	Возврат Меню;

КонецФункции

&НаКлиенте
Процедура ПослеВыбораПоказателя(ВыбранныйПоказатель, ДополнительныеПараметры) Экспорт

	Если ТипЗнч(ВыбранныйПоказатель) <> Тип("ЭлементСпискаЗначений") Тогда
		Возврат;
	КонецЕсли;

	Если ВыбранныйПоказатель.Значение = Элементы.РассчитатьВсеПоказатели.Имя Тогда

		РазвернутьОбластьПоказателей = Не Элементы.РассчитатьВсеПоказатели.Пометка;
		ОбщегоНазначенияСлужебныйКлиент.УстановитьВидимостьПанелиПоказателей(Элементы, РазвернутьОбластьПоказателей);

	Иначе
		РассчитатьПоказатели(ВыбранныйПоказатель.Значение);
	КонецЕсли;

КонецПроцедуры

// Выполняет расчет и вывод показателей выделенной области ячеек.
// См. обработчик события ОтчетТабличныйДокументПриАктивизацииОбласти.
//
&НаКлиенте
Процедура РассчитатьПоказателиДинамически()

	РассчитатьПоказатели();

КонецПроцедуры

&НаКлиенте
Процедура РассчитатьПоказатели(ТекущаяКоманда = "")

	Если Не НастройкиОтчета.ВыводитьСуммуВыделенныхЯчеек Тогда

		СохраняемыеВНастройкахДанныеМодифицированы = Истина;
		Возврат;

	КонецЕсли;

	Показатель = "";
	ОбщегоНазначенияСлужебныйКлиент.РассчитатьПоказатели(ЭтотОбъект, "ОтчетТабличныйДокумент", ТекущаяКоманда, 2);

КонецПроцедуры

#КонецОбласти

#Область УниверсальныйПоиск

&НаКлиенте
Процедура ПерейтиКНастройкам(РасширенныйРежим = Неопределено)

	ВыполнятьЗамеры = НастройкиОтчета.ВыполнятьЗамеры И ЗначениеЗаполнено(НастройкиОтчета.КлючЗамеров);
	Если ВыполнятьЗамеры Тогда
		МодульОценкаПроизводительностиКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("ОценкаПроизводительностиКлиент");
		ИдентификаторЗамера = МодульОценкаПроизводительностиКлиент.ЗамерВремени(
			НастройкиОтчета.КлючЗамеров + ".Настройки", Ложь, Ложь);
	КонецЕсли;

	ПараметрыФормы = Новый Структура;
	ОбщегоНазначенияКлиентСервер.ДополнитьСтруктуру(ПараметрыФормы, ФормаПараметры, Истина);

	Если РасширенныйРежим = Истина Тогда

		НастройкиОтчета.ФормаНастроекРасширенныйРежим = 1;

		ПараметрыФормы.Вставить("ИмяСтраницы", "СтраницаОтборы");
		ПараметрыФормы.Вставить("СброситьПользовательскиеНастройки", Истина);

	КонецЕсли;

	ПараметрыФормы.Вставить("КлючВарианта", Строка(КлючТекущегоВарианта));
	ПараметрыФормы.Вставить("Вариант", Отчет.КомпоновщикНастроек.Настройки);
	ПараметрыФормы.Вставить("ПользовательскиеНастройки", Отчет.КомпоновщикНастроек.ПользовательскиеНастройки);
	ПараметрыФормы.Вставить("НастройкиОтчета", НастройкиОтчета);
	ПараметрыФормы.Вставить("ВариантНаименование", Строка(ОтчетНаименованиеТекущегоВарианта));

	Обработчик = Новый ОписаниеОповещения("ПрименитьНастройкиИПереформироватьОтчет", ЭтотОбъект);
	ОткрытьФорму(НастройкиОтчета.ПолноеИмя + ".ФормаНастроек", ПараметрыФормы, ЭтотОбъект,,,, Обработчик);

	Если ВыполнятьЗамеры Тогда
		МодульОценкаПроизводительностиКлиент.ЗавершитьЗамерВремени(ИдентификаторЗамера);
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Функция ПереходКНастройкамВыполнен(Запрос = Неопределено)

	ЗапросНормализованный = ВРег(?(ЗначениеЗаполнено(Запрос), Запрос, Показатель));

	Если ЗапросНормализованный = "СКД" Тогда

		СброситьУниверсальныйПоиск();
		ПерейтиКНастройкам(НастройкиОтчета.РазрешеноИзменятьВарианты);

		Возврат Истина;

	КонецЕсли;

	Возврат Ложь;

КонецФункции

&НаКлиенте
Процедура СброситьУниверсальныйПоиск()

	Показатель = "";
	Элементы.Показатель.ОбновитьТекстРедактирования();

КонецПроцедуры

&НаКлиенте
Функция ПодходящиеЗначенияУниверсальногоПоиска(Запрос)

	ПодходящиеЗначения = Новый СписокЗначений;
	МаксимальноеКоличествоПодходящихЗначений = 50;

	ПараметрыПоиска = ПараметрыУниверсальногоПоиска(Запрос);

	Если Не ЗначениеЗаполнено(ПараметрыПоиска.СтрокаПоиска) Тогда
		Возврат ПодходящиеЗначения;
	КонецЕсли;

	ОформитьПолеУниверсальногоПоиска(ПараметрыПоиска.УправляющиеСимволы);

	ПоляПоискаПоТипам = ПоляУниверсальногоПоискаПоТипам(
		НастройкиОтчета.АдресСхемы, Отчет.КомпоновщикНастроек.Настройки);

	Если ПоляПоискаПоТипам.Количество() = 0 Тогда
		Возврат ПодходящиеЗначения;
	КонецЕсли;

	Если ПараметрыУниверсальногоПоискаПрименимыКСсылкам(ПараметрыПоиска) Тогда
		НайтиПодходящиеЗначенияУниверсальногоПоиска(ПодходящиеЗначения, ПоляПоискаПоТипам, ПараметрыПоиска);
	КонецЕсли;

	НайтиПодходящиеЗначенияУниверсальногоПоискаБулево(ПодходящиеЗначения, ПоляПоискаПоТипам, ПараметрыПоиска);

	НайтиПодходящиеЗначенияУниверсальногоПоискаДаты(ПодходящиеЗначения, ПоляПоискаПоТипам, ПараметрыПоиска);

	НайтиПодходящиеЗначенияУниверсальногоПоискаСтроки(ПодходящиеЗначения, ПоляПоискаПоТипам, ПараметрыПоиска);

	НайтиПодходящиеЗначенияУниверсальногоПоискаЧисла(ПодходящиеЗначения, ПоляПоискаПоТипам, ПараметрыПоиска);

	Если ПодходящиеЗначения.Количество() = 0 Тогда

		Если СтрДлина(ПараметрыПоиска.СтрокаПоиска) > 2 Тогда
			Сообщение = НСтр("ru = 'Совпадений не найдено'");
		Иначе
			Сообщение = НСтр("ru = 'Продолжите ввод...'");
		КонецЕсли;

		СообщениеФорматированное = Новый ФорматированнаяСтрока(Сообщение, , WebЦвета.НейтральноСерый);
		ПодходящиеЗначения.Добавить("", СообщениеФорматированное);

	КонецЕсли;

	Если ПодходящиеЗначения.Количество() <= МаксимальноеКоличествоПодходящихЗначений Тогда
		Возврат ПодходящиеЗначения;
	КонецЕсли;

	ПодходящиеЗначенияНормализованные = Новый СписокЗначений;

	Для НомерЭлемента = 1 По МаксимальноеКоличествоПодходящихЗначений Цикл
		ЗаполнитьЗначенияСвойств(ПодходящиеЗначенияНормализованные.Добавить(), ПодходящиеЗначения[НомерЭлемента - 1]);
	КонецЦикла;

	Возврат ПодходящиеЗначенияНормализованные;

КонецФункции

&НаКлиенте
Функция ПараметрыУниверсальногоПоиска(Запрос)

	ПараметрыПоиска = Новый Структура;
	ПараметрыПоиска.Вставить("СтрокаПоиска", Запрос);
	ПараметрыПоиска.Вставить("СтрокаПоискаНормализованная", Запрос);
	ПараметрыПоиска.Вставить("ЧислоПоиска", Неопределено);
	ПараметрыПоиска.Вставить("ДатаПоиска", Дата(1, 1, 1));
	ПараметрыПоиска.Вставить("УправляющиеСимволы", "");

	ПервыйСимвол = Лев(Запрос, 1);
	ПервыеДваСимвола = Лев(Запрос, 2);

	Если ПервыеДваСимвола = ">=" Или ПервыеДваСимвола = "<=" Или ПервыеДваСимвола = "<>" Тогда

		ПараметрыПоиска.СтрокаПоиска = Сред(Запрос, 3);
		ПараметрыПоиска.УправляющиеСимволы = ПервыеДваСимвола;

	ИначеЕсли ПервыйСимвол = "-" Или ПервыйСимвол = ">" Или ПервыйСимвол = "<" Или ПервыйСимвол = "=" Тогда

		ПараметрыПоиска.СтрокаПоиска = Сред(Запрос, 2);
		ПараметрыПоиска.УправляющиеСимволы = ПервыйСимвол;

	КонецЕсли;

	Если ОбщегоНазначенияКлиентСервер.ЭтоЧисло(ПараметрыПоиска.СтрокаПоиска) Тогда

		ОписаниеЧисла = Новый ОписаниеТипов("Число");
		ПараметрыПоиска.ЧислоПоиска = ОписаниеЧисла.ПривестиЗначение(ПараметрыПоиска.СтрокаПоиска);

	КонецЕсли;

	ПараметрыПоиска.ДатаПоиска = ОбщегоНазначенияКлиентСервер.СтрокаВДату(ПараметрыПоиска.СтрокаПоиска);

	ПараметрыПоиска.СтрокаПоискаНормализованная = СтрЗаменить(ПараметрыПоиска.СтрокаПоиска, """", "_");

	Возврат ПараметрыПоиска;

КонецФункции

&НаКлиенте
Процедура ОформитьПолеУниверсальногоПоиска(УправляющиеСимволы)

	ПолеЗапроса = Элементы.Показатель;

	Если УправляющиеСимволы = "-" Тогда

		ПолеЗапроса.ЦветТекста = WebЦвета.Красный;

	ИначеЕсли Не ПустаяСтрока(УправляющиеСимволы) Тогда

		ПолеЗапроса.ЦветТекста = WebЦвета.Зеленый;

	Иначе

		ПолеЗапроса.ЦветТекста = Новый Цвет;

	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Функция ПараметрыУниверсальногоПоискаПрименимыКСсылкам(ПараметрыПоиска)

	НедопустимыеУправляющиеСимволы = Новый Массив;
	НедопустимыеУправляющиеСимволы.Добавить(">");
	НедопустимыеУправляющиеСимволы.Добавить(">=");
	НедопустимыеУправляющиеСимволы.Добавить("<");
	НедопустимыеУправляющиеСимволы.Добавить("<=");

	Если НедопустимыеУправляющиеСимволы.Найти(ПараметрыПоиска.УправляющиеСимволы) <> Неопределено Тогда
		Возврат Ложь;
	КонецЕсли;

	Возврат СтрДлина(ПараметрыПоиска.СтрокаПоиска) > 2 
		Или ОбщегоНазначенияКлиентСервер.ЭтоЧисло(ПараметрыПоиска.СтрокаПоиска);

КонецФункции

&НаКлиенте
Процедура НайтиПодходящиеЗначенияУниверсальногоПоискаЧисла(ПодходящиеЗначения, ПоляПоискаПоТипам, ПараметрыПоиска)

	Если Не ОбщегоНазначенияКлиентСервер.ЭтоЧисло(ПараметрыПоиска.СтрокаПоиска) Тогда
		Возврат;
	КонецЕсли;

	ПоляПоиска = ПоляПоискаПоТипам[Тип("Число")];

	Если ПоляПоиска = Неопределено Тогда
		Возврат;
	КонецЕсли;

	ПодходящиеЗначенияДляЧисла = Новый СписокЗначений;

	ДоступныеПоляПоиска = ДоступныеПоляПоискаЧисла(ПоляПоиска, ПараметрыПоиска.ЧислоПоиска,
		ПараметрыПоиска.УправляющиеСимволы);

	Для Каждого ПолеПоиска Из ДоступныеПоляПоиска Цикл

		СвойстваПоиска = СвойстваУниверсальногоПоиска(ПолеПоиска.Ключ, ПараметрыПоиска.ЧислоПоиска,
			ПараметрыПоиска.УправляющиеСимволы);
		ВариантыПоиска = Новый Массив;
		ВариантыПоиска.Добавить(СвойстваПоиска);
		ПодходящиеЗначенияДляЧисла.Добавить(ВариантыПоиска, ПредставлениеРезультатПоискаКлиент(
			ПолеПоиска.Значение, СвойстваПоиска.ВидСравнения, СвойстваПоиска.ПравоеЗначение));

	КонецЦикла;

	ПодходящиеЗначенияДляЧисла.СортироватьПоПредставлению();
	ОбщегоНазначенияКлиентСервер.ДополнитьСписок(ПодходящиеЗначения, ПодходящиеЗначенияДляЧисла);

КонецПроцедуры

&НаКлиенте
Функция ДоступныеПоляПоискаЧисла(ПоляПоиска, ЗначениеПоиска, УправляющиеСимволы)

	Условие = УсловиеУниверсальногоПоиска(ЗначениеПоиска, УправляющиеСимволы);

	Если Условие = ВидСравненияКомпоновкиДанных.Равно Тогда
		Возврат ОбщегоНазначенияКлиент.СкопироватьРекурсивно(ПоляПоиска);
	КонецЕсли;

	ДоступныеПоляПоиска = Новый Соответствие;
	ДоступныеПоляПараметров = Отчет.КомпоновщикНастроек.Настройки.ДоступныеПоляПараметровДанных;

	Для Каждого ПолеПоиска Из ПоляПоиска Цикл

		Если ДоступныеПоляПараметров.НайтиПоле(ПолеПоиска.Ключ) = Неопределено Тогда
			ДоступныеПоляПоиска.Вставить(ПолеПоиска.Ключ, ПолеПоиска.Значение);
		КонецЕсли;

	КонецЦикла;

	Возврат ДоступныеПоляПоиска;

КонецФункции

&НаСервереБезКонтекста
Процедура НайтиПодходящиеЗначенияУниверсальногоПоиска(ПодходящиеЗначения, ПоляПоискаПоТипам, ПараметрыПоиска)

	Если Не ЗначениеЗаполнено(ПараметрыПоиска.СтрокаПоиска) Тогда
		Возврат;
	КонецЕсли;

	ТекстыЗапросов = Новый Массив;
	Для Каждого Элемент Из ПоляПоискаПоТипам Цикл

		Если Не ОбщегоНазначения.ЭтоСсылка(Элемент.Ключ) Тогда
			Продолжить;
		КонецЕсли;

		ОбъектМетаданных = Метаданные.НайтиПоТипу(Элемент.Ключ);
		Если Метаданные.Перечисления.Содержит(ОбъектМетаданных) Тогда
			Для Каждого ЭлементПоле Из Элемент.Значение Цикл
				Для Каждого Значение Из ОбъектМетаданных.ЗначенияПеречисления Цикл
					Если СтрНачинаетсяС(ВРег(Значение.Синоним), ВРег(ПараметрыПоиска.СтрокаПоиска)) Тогда
						ЗначениеПеречисления = ОбщегоНазначения.ПредопределенныйЭлемент(ОбъектМетаданных.ПолноеИмя()
							+ "." + Значение.Имя);
						СвойстваПоиска = СвойстваУниверсальногоПоиска(ЭлементПоле.Ключ, ЗначениеПеречисления,
							ПараметрыПоиска.УправляющиеСимволы);
						ВариантыПоиска = Новый Массив;
						ВариантыПоиска.Добавить(СвойстваПоиска);
						ПодходящиеЗначения.Добавить(ВариантыПоиска, ПредставлениеРезультатПоиска(
							ЭлементПоле.Значение, СвойстваПоиска.ВидСравнения, СвойстваПоиска.ПравоеЗначение));
					КонецЕсли;
				КонецЦикла;
			КонецЦикла;
			Продолжить;
		КонецЕсли;

		Если Не ПравоДоступа("Чтение", ОбъектМетаданных) Тогда
			Продолжить;
		КонецЕсли;

		ТекстЗапроса = ТекстЗапросаПоОбъектуПоиска(ОбъектМетаданных, ПараметрыПоиска);
		Если ТекстыЗапросов.Количество() > 0 Тогда
			ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ВЫБРАТЬ РАЗРЕШЕННЫЕ", "ВЫБРАТЬ"); // @query-part-1, @query-part-2
		КонецЕсли;
		ТекстыЗапросов.Добавить(ТекстЗапроса);

	КонецЦикла;

	Если ТекстыЗапросов.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;

	ТекстЗапроса = СтрСоединить(ТекстыЗапросов, Символы.ПС + "ОБЪЕДИНИТЬ ВСЕ" + Символы.ПС); // @query-part
	Запрос = Новый Запрос(ТекстЗапроса);

	Если СтрНайти(ТекстЗапроса, "&ЧислоПоиска") > 0 Тогда
		Запрос.УстановитьПараметр("ЧислоПоиска", ПараметрыПоиска.ЧислоПоиска);
	КонецЕсли;

	Если СтрНайти(ТекстЗапроса, "&ДатаПоиска") > 0 Тогда
		Запрос.УстановитьПараметр("ДатаПоиска", ПараметрыПоиска.ДатаПоиска);
	КонецЕсли;

	Выборка = Запрос.Выполнить().Выбрать();

	ИндексВариантовПоиска = Новый Соответствие;
	ИндексПредставленийПоиска = Новый Соответствие;

	ИндексДополнительныхЗначений = Новый Соответствие;
	ДополнительныеЗначения = Новый СписокЗначений;

	Пока Выборка.Следующий() Цикл

		ПоляПоиска = ПоляПоискаПоТипам[ТипЗнч(Выборка.Ссылка)];
		Для Каждого ПолеПоиска Из ПоляПоиска Цикл

			СвойстваПоиска = СвойстваУниверсальногоПоиска(ПолеПоиска.Ключ, Выборка.Ссылка,
				ПараметрыПоиска.УправляющиеСимволы);
			ВариантыПоиска = ИндексВариантовПоиска[СвойстваПоиска.ПравоеЗначение];
			Если ВариантыПоиска = Неопределено Тогда

				ПредставлениеПоиска = ПредставлениеУниверсальногоПоискаСсылки(
					Выборка, ПолеПоиска.Значение, СвойстваПоиска.ВидСравнения, ПараметрыПоиска.СтрокаПоиска);

				ИндексПредставленийПоиска.Вставить(СвойстваПоиска.ПравоеЗначение, ПредставлениеПоиска);
				ВариантыПоиска = Новый Массив;

			КонецЕсли;

			ВариантыПоиска.Добавить(СвойстваПоиска);
			ИндексВариантовПоиска.Вставить(СвойстваПоиска.ПравоеЗначение, ВариантыПоиска);

			Если Не ЗначениеЗаполнено(Выборка.ПолеПоУсловию) 
				Или ИндексДополнительныхЗначений[ПолеПоиска.Ключ] 	<> Неопределено Тогда

				Продолжить;
			КонецЕсли;

			ПутьКДанным = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				"%1.%2", ПолеПоиска.Ключ, Выборка.ПолеПоУсловию);

			РеквизитПоля = Новый ПолеКомпоновкиДанных(ПутьКДанным);
			СвойстваПоиска = СвойстваУниверсальногоПоиска(
				РеквизитПоля, ПараметрыПоиска.СтрокаПоиска, ПараметрыПоиска.УправляющиеСимволы);
				
			ПутьКДаннымПредставление = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				"%1.%2", ПолеПоиска.Значение, Выборка.ПолеПоУсловию);	
				
			ВариантыПоиска = Новый Массив;
			ВариантыПоиска.Добавить(СвойстваПоиска);
			ДополнительныеЗначения.Добавить(ВариантыПоиска, ПредставлениеРезультатПоиска(ПутьКДаннымПредставление,
				СвойстваПоиска.ВидСравнения, ПараметрыПоиска.СтрокаПоиска));

			ИндексДополнительныхЗначений.Вставить(ПолеПоиска.Ключ, Истина);

		КонецЦикла;

	КонецЦикла;

	Для Каждого ИндексЗначения Из ИндексВариантовПоиска Цикл
		ПодходящиеЗначения.Добавить(ИндексЗначения.Значение, ИндексПредставленийПоиска[ИндексЗначения.Ключ]);
	КонецЦикла;

	ПодходящиеЗначения.СортироватьПоПредставлению();
	ДополнительныеЗначения.СортироватьПоПредставлению();

	ОбщегоНазначенияКлиентСервер.ДополнитьСписок(ПодходящиеЗначения, ДополнительныеЗначения);

КонецПроцедуры

&НаКлиенте
Процедура НайтиПодходящиеЗначенияУниверсальногоПоискаБулево(ПодходящиеЗначения, ПоляПоискаПоТипам, ПараметрыПоиска)

	Если Не ЗначениеЗаполнено(ПараметрыПоиска.СтрокаПоиска) Тогда
		Возврат;
	КонецЕсли;

	ПоляПоиска = ПоляПоискаПоТипам[Тип("Булево")];

	Если ПоляПоиска = Неопределено Тогда
		Возврат;
	КонецЕсли;

	ПодходящиеЗначенияДляБулево = Новый СписокЗначений;
	
	// Поиск по имени колонки
	Для Каждого ПолеПоиска Из ПоляПоиска Цикл
		Если СтрНачинаетсяС(ВРег(ПолеПоиска.Значение), ВРег(ПараметрыПоиска.СтрокаПоиска)) Тогда
			СвойстваПоиска = СвойстваУниверсальногоПоиска(ПолеПоиска.Ключ, Истина, ПараметрыПоиска.УправляющиеСимволы);
			ВариантыПоиска = Новый Массив;
			ВариантыПоиска.Добавить(СвойстваПоиска);
			ПодходящиеЗначенияДляБулево.Добавить(ВариантыПоиска, ПредставлениеРезультатПоискаКлиент(
				ПолеПоиска.Значение, СвойстваПоиска.ВидСравнения, СвойстваПоиска.ПравоеЗначение));
			СвойстваПоиска = СвойстваУниверсальногоПоиска(ПолеПоиска.Ключ, Ложь, ПараметрыПоиска.УправляющиеСимволы);
			ВариантыПоиска = Новый Массив;
			ВариантыПоиска.Добавить(СвойстваПоиска);
			ПодходящиеЗначенияДляБулево.Добавить(ВариантыПоиска, ПредставлениеРезультатПоискаКлиент(
				ПолеПоиска.Значение, СвойстваПоиска.ВидСравнения, СвойстваПоиска.ПравоеЗначение));
		КонецЕсли;
	КонецЦикла;
	
	// Поиск по значениям Булево
	// АПК:1391-выкл Проверка значений, которые ввел пользователь.
	Если СтрСравнить(ПараметрыПоиска.СтрокаПоиска, НСтр("ru = 'Да'")) = 0 
		Или СтрСравнить(ПараметрыПоиска.СтрокаПоиска, НСтр("ru = 'Истина'")) = 0 
		Или СтрСравнить(ПараметрыПоиска.СтрокаПоиска, НСтр("ru = 'Включено'")) = 0 Тогда
		Для Каждого ПолеПоиска Из ПоляПоиска Цикл
			СвойстваПоиска = СвойстваУниверсальногоПоиска(ПолеПоиска.Ключ, Истина, ПараметрыПоиска.УправляющиеСимволы);
			ВариантыПоиска = Новый Массив;
			ВариантыПоиска.Добавить(СвойстваПоиска);
			ПодходящиеЗначенияДляБулево.Добавить(ВариантыПоиска, ПредставлениеРезультатПоискаКлиент(
				ПолеПоиска.Значение, СвойстваПоиска.ВидСравнения, СвойстваПоиска.ПравоеЗначение));
		КонецЦикла;
	ИначеЕсли СтрСравнить(ПараметрыПоиска.СтрокаПоиска, НСтр("ru = 'Нет'")) = 0 
		Или СтрСравнить(ПараметрыПоиска.СтрокаПоиска, НСтр("ru = 'Ложь'")) = 0 
		Или СтрСравнить(ПараметрыПоиска.СтрокаПоиска, НСтр("ru = 'Выключено'")) = 0 Тогда
		Для Каждого ПолеПоиска Из ПоляПоиска Цикл
			СвойстваПоиска = СвойстваУниверсальногоПоиска(ПолеПоиска.Ключ, Ложь, ПараметрыПоиска.УправляющиеСимволы);
			ВариантыПоиска = Новый Массив;
			ВариантыПоиска.Добавить(СвойстваПоиска);
			ПодходящиеЗначенияДляБулево.Добавить(ВариантыПоиска, ПредставлениеРезультатПоискаКлиент(
				ПолеПоиска.Значение, СвойстваПоиска.ВидСравнения, СвойстваПоиска.ПравоеЗначение));
		КонецЦикла;
	КонецЕсли;
	// АПК:1391-вкл

	ПодходящиеЗначенияДляБулево.СортироватьПоПредставлению();
	ОбщегоНазначенияКлиентСервер.ДополнитьСписок(ПодходящиеЗначения, ПодходящиеЗначенияДляБулево);

КонецПроцедуры

&НаКлиенте
Процедура НайтиПодходящиеЗначенияУниверсальногоПоискаСтроки(ПодходящиеЗначения, ПоляПоискаПоТипам, ПараметрыПоиска)

	Если Не ЗначениеЗаполнено(ПараметрыПоиска.СтрокаПоиска) Или ЗначениеЗаполнено(ПараметрыПоиска.ДатаПоиска)
		Или ОтчетТабличныйДокумент.НайтиТекст(ПараметрыПоиска.СтрокаПоиска,,,,,, Истина) = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	// АПК:1391-выкл Проверка значений, которые ввел пользователь.
	Если СтрСравнить(ПараметрыПоиска.СтрокаПоиска, НСтр("ru = 'Да'")) = 0 
		Или СтрСравнить(ПараметрыПоиска.СтрокаПоиска, НСтр("ru = 'Истина'")) = 0 
		Или СтрСравнить(ПараметрыПоиска.СтрокаПоиска, НСтр("ru = 'Включено'")) = 0
		Или СтрСравнить(ПараметрыПоиска.СтрокаПоиска, НСтр("ru = 'Нет'")) = 0 
		Или СтрСравнить(ПараметрыПоиска.СтрокаПоиска, НСтр("ru = 'Ложь'")) = 0 
		Или СтрСравнить(ПараметрыПоиска.СтрокаПоиска, НСтр("ru = 'Выключено'")) = 0 Тогда
		Возврат;
	КонецЕсли;
	// АПК:1391-вкл

	Для Каждого ТипПоиска Из ПоляПоискаПоТипам Цикл
		Для Каждого ПолеПоиска Из ТипПоиска.Значение Цикл
			Если СтрНачинаетсяС(ВРег(ПолеПоиска.Значение), ВРег(ПараметрыПоиска.СтрокаПоиска)) Тогда
				Возврат;
			КонецЕсли;
		КонецЦикла;
	КонецЦикла;

	ПоляПоиска = ПоляПоискаПоТипам[Тип("Строка")];

	Если ПоляПоиска = Неопределено Тогда
		Возврат;
	КонецЕсли;

	ПодходящиеЗначенияДляСтроки = Новый СписокЗначений;

	Для Каждого ПолеПоиска Из ПоляПоиска Цикл
		СвойстваПоиска = СвойстваУниверсальногоПоиска(ПолеПоиска.Ключ, ПараметрыПоиска.СтрокаПоиска,
			ПараметрыПоиска.УправляющиеСимволы);
		ВариантыПоиска = Новый Массив;
		ВариантыПоиска.Добавить(СвойстваПоиска);
		ПредставлениеРезультата = ПредставлениеРезультатПоискаКлиент(
			ПолеПоиска.Значение, СвойстваПоиска.ВидСравнения, СвойстваПоиска.ПравоеЗначение);
		СуществуетЗначение = Ложь;
		Для Каждого Строка Из ПодходящиеЗначения Цикл
			Если СтрСравнить(Строка.Представление, ПредставлениеРезультата) = 0 Тогда
				СуществуетЗначение = Истина;
				Прервать;
			КонецЕсли;
		КонецЦикла;
		Если СуществуетЗначение Тогда
			Продолжить;
		КонецЕсли;
		ПодходящиеЗначенияДляСтроки.Добавить(ВариантыПоиска, ПредставлениеРезультата);
	КонецЦикла;

	ПодходящиеЗначенияДляСтроки.СортироватьПоПредставлению();
	ОбщегоНазначенияКлиентСервер.ДополнитьСписок(ПодходящиеЗначения, ПодходящиеЗначенияДляСтроки);

КонецПроцедуры

&НаКлиенте
Процедура НайтиПодходящиеЗначенияУниверсальногоПоискаДаты(ПодходящиеЗначения, ПоляПоискаПоТипам, ПараметрыПоиска)

	Если Не ЗначениеЗаполнено(ПараметрыПоиска.СтрокаПоиска) Или Не ЗначениеЗаполнено(ПараметрыПоиска.ДатаПоиска)
		Или ОбщегоНазначенияКлиентСервер.ЭтоЧисло(ПараметрыПоиска.СтрокаПоиска) 
		Или ОтчетТабличныйДокумент.НайтиТекст(ПараметрыПоиска.СтрокаПоиска,,,,,, Истина) = Неопределено Тогда
		Возврат;
	КонецЕсли;

	ПоляПоиска = ПоляПоискаПоТипам[Тип("Дата")];

	Если ПоляПоиска = Неопределено Тогда
		Возврат;
	КонецЕсли;

	ПодходящиеЗначенияДляДаты = Новый СписокЗначений;

	Для Каждого ПолеПоиска Из ПоляПоиска Цикл
		СвойстваПоиска = СвойстваУниверсальногоПоиска(ПолеПоиска.Ключ, ПараметрыПоиска.ДатаПоиска,
			ПараметрыПоиска.УправляющиеСимволы);
		ВариантыПоиска = Новый Массив;
		ВариантыПоиска.Добавить(СвойстваПоиска);
		ПредставлениеДаты = ?(СвойстваПоиска.ПравоеЗначение = НачалоДня(СвойстваПоиска.ПравоеЗначение), 
			Формат(СвойстваПоиска.ПравоеЗначение, "ДЛФ=Д"), СвойстваПоиска.ПравоеЗначение);
		ПодходящиеЗначенияДляДаты.Добавить(ВариантыПоиска, ПредставлениеРезультатПоискаКлиент(
			ПолеПоиска.Значение, СвойстваПоиска.ВидСравнения, ПредставлениеДаты));
	КонецЦикла;

	ПодходящиеЗначенияДляДаты.СортироватьПоПредставлению();
	ОбщегоНазначенияКлиентСервер.ДополнитьСписок(ПодходящиеЗначения, ПодходящиеЗначенияДляДаты);

КонецПроцедуры

&НаСервереБезКонтекста
Функция ТекстЗапросаПоОбъектуПоиска(Объект, ПараметрыПоиска)

	ШаблонТекстаЗапроса =
	"ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ ПЕРВЫЕ 5
	|	""&ПолноеИмяОбъекта"" КАК ПолноеИмяОбъекта,
	|	Ссылка КАК Ссылка,
	|	&ПолеПоУсловию КАК ПолеПоУсловию,
	|	&ДополнительныеДанные КАК ДополнительныеДанные
	|ИЗ
	|	&ПолноеИмяОбъекта
	|ГДЕ
	|	&Условие
	|";

	ТекстЗапроса = СтрЗаменить(ШаблонТекстаЗапроса, "&ПолноеИмяОбъекта", Объект.ПолноеИмя());
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ПолеПоУсловию", ПолеТекстаЗапросаПоОбъектуПоиска(Объект,
		ПараметрыПоиска));
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&Условие", УсловиеТекстаЗапросаПоОбъектуПоиска(Объект, ПараметрыПоиска));

	Возврат СтрЗаменить(ТекстЗапроса, "&ДополнительныеДанные", ДополнительныеДанныеТекстаЗапросаПоОбъектуПоиска(Объект));

КонецФункции

// Параметры:
//  Объект - ОбъектМетаданных
//  ПараметрыПоиска - Структура:
//    * СтрокаПоискаНормализованная - Строка
// 
// Возвращаемое значение:
//  Строка
//
&НаСервереБезКонтекста
Функция ПолеТекстаЗапросаПоОбъектуПоиска(Объект, ПараметрыПоиска)

	ОписаниеПоляПоУсловию = Новый Массив;
	Поля = Объект.ВводПоСтроке; // СписокПолей

	Для Каждого Поле Из Поля Цикл

		ТипРеквизита = ТипРеквизитаПоиска(Объект, Поле.Имя);
		Если Не ТипРеквизита.СодержитТип(Тип("Строка")) Тогда
			Продолжить;
		КонецЕсли;
		
		ПолеПоУсловию = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			"КОГДА ВЫРАЗИТЬ(%1 КАК СТРОКА(150)) ПОДОБНО %2 СПЕЦСИМВОЛ ""~"" ТОГДА ""%3""", Поле.Имя, """%"
			+ ОбщегоНазначения.СформироватьСтрокуДляПоискаВЗапросе(ПараметрыПоиска.СтрокаПоискаНормализованная) + "%""",
			ПредставлениеПоля(Поле.Имя, Объект));
		ОписаниеПоляПоУсловию.Добавить(ПолеПоУсловию);

	КонецЦикла;

	Если ОписаниеПоляПоУсловию.Количество() = 0 Тогда
		Возврат """""";
	КонецЕсли;

	ОписаниеПоляПоУсловию.Вставить(0, "ВЫБОР"); //@query-part
	ОписаниеПоляПоУсловию.Добавить("ИНАЧЕ """""); //@query-part
	ОписаниеПоляПоУсловию.Добавить("КОНЕЦ"); //@query-part

	Возврат СтрСоединить(ОписаниеПоляПоУсловию, " ");

КонецФункции

&НаСервереБезКонтекста
Функция ПредставлениеПоля(ИмяПоля, Объект)
	
	РеквизитОбъекта = Объект.Реквизиты.Найти(ИмяПоля);
	
	Если РеквизитОбъекта = Неопределено Тогда
		Для каждого СтандартныйРеквизит Из Объект.СтандартныеРеквизиты Цикл
			Если СтрСравнить(СтандартныйРеквизит.Имя, ИмяПоля) = 0 Тогда
				РеквизитОбъекта = СтандартныйРеквизит;
				Прервать;
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	
	Если РеквизитОбъекта <> Неопределено Тогда
		Возврат РеквизитОбъекта.Представление();
	КонецЕсли;
	
	
	Возврат ИмяПоля;
	
КонецФункции

// Параметры:
//  Объект - ОбъектМетаданных
//  ПараметрыПоиска - Структура:
//    * СтрокаПоискаНормализованная - Строка
// 
// Возвращаемое значение:
//  Строка
//
&НаСервереБезКонтекста
Функция УсловиеТекстаЗапросаПоОбъектуПоиска(Объект, ПараметрыПоиска)

	Условия = Новый Массив;
	Поля = Объект.ВводПоСтроке; // СписокПолей

	ИменаПолей = Новый Массив;
	Для Каждого Поле Из Поля Цикл
		ИменаПолей.Добавить(Поле.Имя);
	КонецЦикла;
	
	// Расширение списка полей для документов
	ЧастиПолногоИмени = СтрРазделить(Объект.ПолноеИмя(), ".");
	Если ЧастиПолногоИмени[0] = "Документ" Тогда
		Если Поля.Найти("Дата") = Неопределено Тогда
			ИменаПолей.Добавить("Дата");
		КонецЕсли;
		Если Поля.Найти("Номер") = Неопределено Тогда
			ИменаПолей.Добавить("Номер");
		КонецЕсли;
	КонецЕсли;

	Для Каждого ИмяПоля Из ИменаПолей Цикл

		ТипРеквизита = ТипРеквизитаПоиска(Объект, ИмяПоля);
		Если ТипРеквизита.СодержитТип(Тип("Строка")) Тогда

			Условие = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				"ВЫРАЗИТЬ(%1 КАК СТРОКА(150)) ПОДОБНО %2 СПЕЦСИМВОЛ ""~""", ИмяПоля, """%"
				+ ОбщегоНазначения.СформироватьСтрокуДляПоискаВЗапросе(ПараметрыПоиска.СтрокаПоискаНормализованная)
				+ "%""");
		ИначеЕсли ТипРеквизита.СодержитТип(Тип("Дата")) И ПараметрыПоиска.ДатаПоиска <> Дата(1, 1, 1) Тогда
			Условие = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				"НачалоПериода(%1) = &ДатаПоиска", ИмяПоля); //@query-part
		ИначеЕсли ТипРеквизита.СодержитТип(Тип("Число")) И ПараметрыПоиска.ЧислоПоиска <> Неопределено Тогда
			Условие = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				"ВЫРАЗИТЬ(%1 КАК ЧИСЛО) = &ЧислоПоиска", ИмяПоля); //@query-part
		Иначе
			Продолжить;
		КонецЕсли;

		Условия.Добавить(Условие);

	КонецЦикла;

	Если Условия.Количество() = 0 Тогда
		Возврат "ЛОЖЬ";
	КонецЕсли;

	Возврат СтрСоединить(Условия, " ИЛИ "); //@query-part

КонецФункции

// Параметры:
//  Объект - ОбъектМетаданных
// 
// Возвращаемое значение:
//  Строка
//
&НаСервереБезКонтекста
Функция ДополнительныеДанныеТекстаЗапросаПоОбъектуПоиска(Объект)

	ДополнительныеДанные = Новый Массив;

	Исключения = Новый Массив;
	Исключения.Добавить("Наименование");
	Исключения.Добавить("Номер");

	Поля = Объект.ВводПоСтроке; // СписокПолей

	Для Каждого Поле Из Поля Цикл

		Если Исключения.Найти(Поле.Имя) <> Неопределено Тогда
			Продолжить;
		КонецЕсли;

		ТипРеквизита = ТипРеквизитаПоиска(Объект, Поле.Имя);

		Если Не ТипРеквизита.СодержитТип(Тип("Строка")) Тогда
			Продолжить;
		КонецЕсли;

		Данные = """" + ПредставлениеПоля(Поле.Имя, Объект) + ": "" + " + Поле.Имя;
		ДополнительныеДанные.Добавить(Данные);

	КонецЦикла;

	Если ДополнительныеДанные.Количество() = 0 Тогда
		Возврат """""";
	КонецЕсли;

	Возврат СтрСоединить(ДополнительныеДанные, " + "", """);

КонецФункции

// Параметры:
//  Объект - ОбъектМетаданных
//  ИмяПоля - Строка
// 
// Возвращаемое значение:
//  - ОписаниеТипов
//
&НаСервереБезКонтекста
Функция ТипРеквизитаПоиска(Объект, ИмяПоля)

	Для Каждого ОписаниеРеквизита Из Объект.СтандартныеРеквизиты Цикл

		Если ОписаниеРеквизита.Имя = ИмяПоля Тогда
			Возврат ОписаниеРеквизита.Тип;
		КонецЕсли;

	КонецЦикла;

	ОписаниеРеквизита = Объект.Реквизиты.Найти(ИмяПоля);

	Если ОписаниеРеквизита <> Неопределено Тогда
		Возврат ОписаниеРеквизита.Тип;
	КонецЕсли;

	Возврат Новый ОписаниеТипов;

КонецФункции

&НаСервереБезКонтекста
Функция ПредставлениеУниверсальногоПоискаСсылки(Данные, ПолеПоиска, Условие, СтрокаПоиска)

	ПредставлениеЗначения = Строка(Данные.Ссылка);
	Для Каждого СлужебныйСимвол Из СтрРазделить("< >", " ") Цикл
		ПредставлениеЗначения = СтрЗаменить(ПредставлениеЗначения, СлужебныйСимвол, "");
	КонецЦикла;

	Если ЗначениеЗаполнено(Данные.ДополнительныеДанные) Тогда
		ПредставлениеЗначения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = '%1 (%2)'"), Строка(Данные.Ссылка), Данные.ДополнительныеДанные);
	КонецЕсли;

	ФрагментУсловия = СтроковыеФункции.ФорматированнаяСтрока(ШаблонФрагментаУсловия(Условие));

	НачалоСтрокиПоиска = СтрНайти(ВРег(ПредставлениеЗначения), ВРег(СтрокаПоиска));
	КонецСтрокиПоиска = НачалоСтрокиПоиска + СтрДлина(СтрокаПоиска);
	ДлинаНайденногоФрагмента = ?(НачалоСтрокиПоиска = 0, 0, СтрДлина(СтрокаПоиска));

	ФрагментДоСтрокиПоиска = Лев(ПредставлениеЗначения, НачалоСтрокиПоиска - 1);
	ФрагментСтрокиПоиска = СтроковыеФункции.ФорматированнаяСтрока(ШаблонФрагментаСтрокиПоиска(
		Сред(ПредставлениеЗначения, НачалоСтрокиПоиска, ДлинаНайденногоФрагмента)));
	ФрагментПослеСтрокиПоиска = Сред(ПредставлениеЗначения, КонецСтрокиПоиска);

	Возврат Новый ФорматированнаяСтрока(ПолеПоиска, ФрагментУсловия, ФрагментДоСтрокиПоиска, ФрагментСтрокиПоиска,
		ФрагментПослеСтрокиПоиска);

КонецФункции

&НаКлиенте
Функция ПредставлениеРезультатПоискаКлиент(Знач ПолеПоиска, Знач Условие, Знач ЗначениеПоиска)

	СтрокаУсловия = СтрокаУсловияПоиска(ПолеПоиска, Условие, ЗначениеПоиска);
	ФрагментУсловия = СтроковыеФункцииКлиент.ФорматированнаяСтрока(ШаблонФрагментаУсловия(СтрокаУсловия));
	ФрагментСтрокиПоиска = СтроковыеФункцииКлиент.ФорматированнаяСтрока(ШаблонФрагментаСтрокиПоиска(ЗначениеПоиска));
	Возврат ФорматированнаяСтрокаРезультатаПоиска(ПолеПоиска, ФрагментУсловия, ФрагментСтрокиПоиска);

КонецФункции

&НаСервереБезКонтекста
Функция ПредставлениеРезультатПоиска(Знач ПолеПоиска, Знач Условие, Знач ЗначениеПоиска)

	СтрокаУсловия = СтрокаУсловияПоиска(ПолеПоиска, Условие, ЗначениеПоиска);
	ФрагментУсловия = СтроковыеФункции.ФорматированнаяСтрока(ШаблонФрагментаУсловия(СтрокаУсловия));
	ФрагментСтрокиПоиска = СтроковыеФункции.ФорматированнаяСтрока(ШаблонФрагментаСтрокиПоиска(ЗначениеПоиска));
	Возврат ФорматированнаяСтрокаРезультатаПоиска(ПолеПоиска, ФрагментУсловия, ФрагментСтрокиПоиска);

КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция СтрокаУсловияПоиска(Знач ПолеПоиска, Знач Условие, ЗначениеПоиска)

	Результат = ?(ТипЗнч(ЗначениеПоиска) = Тип("Число"), ОператорУниверсальногоПоиска(Условие), НРег(Условие));
	ЗначениеПоиска = Строка(ЗначениеПоиска);
	Возврат Результат;

КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ФорматированнаяСтрокаРезультатаПоиска(Знач ПолеПоиска, Знач ФрагментУсловия, Знач ФрагментСтрокиПоиска)

	Возврат Новый ФорматированнаяСтрока(ПолеПоиска, ФрагментУсловия, """", ФрагментСтрокиПоиска, """");

КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ШаблонФрагментаУсловия(Условие)

	Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = '%1<span style=""color: %2"">%3</span>%4'"), " ", "СкрытыйВариантОтчетаЦвет", 
			НРег(СтрЗаменить(Условие, "<", "&lt;")), " ");

КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ШаблонФрагментаСтрокиПоиска(СтрокаПоиска)

	Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = '<span style=""color: %1; font: %2"">%3</span>'"), "МоиВариантыОтчетовЦвет", "ВажнаяНадписьШрифт",
		СтрокаПоиска);

КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция СвойстваУниверсальногоПоиска(ПолеПоиска, ЗначениеПоиска, УправляющиеСимволы)

	Условие = УсловиеУниверсальногоПоиска(ЗначениеПоиска, УправляющиеСимволы);

	Свойства = Новый Структура;
	Свойства.Вставить("Использование", Истина);
	Свойства.Вставить("ЛевоеЗначение", ПолеПоиска);
	Свойства.Вставить("ВидСравнения", Условие);
	Свойства.Вставить("ПравоеЗначение", ЗначениеПоиска);

	Возврат Свойства;

КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция УсловиеУниверсальногоПоиска(ЗначениеПоиска, УправляющиеСимволы)

	Если ТипЗнч(ЗначениеПоиска) = Тип("Строка") И (Не ЗначениеЗаполнено(УправляющиеСимволы) 
		Или УправляющиеСимволы = "=") Тогда
		Условие = ВидСравненияКомпоновкиДанных.Содержит;
	ИначеЕсли ТипЗнч(ЗначениеПоиска) = Тип("Строка") И (УправляющиеСимволы = "-" Или УправляющиеСимволы = "<>") Тогда
		Условие = ВидСравненияКомпоновкиДанных.НеСодержит;
	ИначеЕсли УправляющиеСимволы = "-" Или УправляющиеСимволы = "<>" Тогда
		Условие = ВидСравненияКомпоновкиДанных.НеРавно;
	ИначеЕсли УправляющиеСимволы = ">" Тогда
		Условие = ВидСравненияКомпоновкиДанных.Больше;
	ИначеЕсли УправляющиеСимволы = ">=" Тогда
		Условие = ВидСравненияКомпоновкиДанных.БольшеИлиРавно;
	ИначеЕсли УправляющиеСимволы = "<" Тогда
		Условие = ВидСравненияКомпоновкиДанных.Меньше;
	ИначеЕсли УправляющиеСимволы = "<=" Тогда
		Условие = ВидСравненияКомпоновкиДанных.МеньшеИлиРавно;
	Иначе
		Условие = ВидСравненияКомпоновкиДанных.Равно;
	КонецЕсли;

	Возврат Условие;

КонецФункции

&НаСервереБезКонтекста
Функция ОператорУниверсальногоПоиска(Условие)

	Операторы = Новый Соответствие;
	Операторы.Вставить(ВидСравненияКомпоновкиДанных.Равно, "=");
	Операторы.Вставить(ВидСравненияКомпоновкиДанных.НеРавно, "<>");
	Операторы.Вставить(ВидСравненияКомпоновкиДанных.Больше, ">");
	Операторы.Вставить(ВидСравненияКомпоновкиДанных.БольшеИлиРавно, ">=");
	Операторы.Вставить(ВидСравненияКомпоновкиДанных.Меньше, "<");
	Операторы.Вставить(ВидСравненияКомпоновкиДанных.МеньшеИлиРавно, "<=");

	Оператор = Операторы[Условие];
	Возврат ?(Оператор = Неопределено, НРег(Условие), Оператор);

КонецФункции

&НаСервереБезКонтекста
Функция ПоляУниверсальногоПоискаПоТипам(АдресСхемы, Знач Настройки)

	ПоляПоискаПоТипам = Новый Соответствие;

	КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
	ОтчетыСервер.ИнициализироватьКомпоновщикНастроек(КомпоновщикНастроек, АдресСхемы);
	КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);

	КомпоновщикНастроек2 = Новый КомпоновщикНастроекКомпоновкиДанных;
	ОтчетыСервер.ИнициализироватьКомпоновщикНастроек(КомпоновщикНастроек2, АдресСхемы);
	КомпоновщикНастроек2.ЗагрузитьНастройки(Настройки);
	КомпоновщикНастроек2.РазвернутьАвтоПоля();

	Коллекции = Новый Массив;
	Коллекции.Добавить(ОписаниеОтборовОтчета(КомпоновщикНастроек));
	Коллекции.Добавить(ОписаниеПолейОтчета(КомпоновщикНастроек.Настройки, КомпоновщикНастроек2.Настройки));

	Для Каждого Коллекция Из Коллекции Цикл
		Для Каждого ОписаниеПоля Из Коллекция Цикл
			Типы = ОписаниеПоля.ТипЗначения.Типы();
			Для Каждого Тип Из Типы Цикл

				ПоляПоТипу = ПоляПоискаПоТипам[Тип];
				Если ПоляПоТипу = Неопределено Тогда
					ПоляПоТипу = Новый Соответствие;
				КонецЕсли;

				ПоляПоТипу.Вставить(ОписаниеПоля.Поле, ОписаниеПоля.Заголовок);
				ПоляПоискаПоТипам.Вставить(Тип, ПоляПоТипу);

			КонецЦикла;
		КонецЦикла;
	КонецЦикла;

	Возврат ПоляПоискаПоТипам;

КонецФункции

&НаСервереБезКонтекста
Функция ОписаниеОтборовОтчета(КомпоновщикНастроек, Отбор = Неопределено, ОписаниеОтборов = Неопределено)

	Если ОписаниеОтборов = Неопределено Тогда
		ОписаниеОтборов = Новый Массив;
	КонецЕсли;

	Настройки = КомпоновщикНастроек.Настройки;
	Если Отбор = Неопределено Тогда
		Отбор = Настройки.Отбор;
	КонецЕсли;

	Для Каждого Элемент Из Отбор.Элементы Цикл
		Если ТипЗнч(Элемент) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда
			ОписаниеОтборовОтчета(КомпоновщикНастроек, Элемент, ОписаниеОтборов);
		Иначе
			ОписаниеПоля = Настройки.ДоступныеПоляОтбора.НайтиПоле(Элемент.ЛевоеЗначение);

			Если ОписаниеПоля <> Неопределено Тогда
				ОписаниеОтборов.Добавить(ОписаниеПоля);
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;

	Возврат ОписаниеОтборов;

КонецФункции

&НаСервереБезКонтекста
Функция ОписаниеПолейОтчета(Настройки, Настройки2)

	ОписаниеПолей = Новый Массив;

	ИндексСтруктурыОтчета = ВариантыОтчетовСлужебный.ИндексСтруктурыОтчетаБезКонтекста(Настройки, Настройки2);

	ИндексПолейОтчета = ИндексСтруктурыОтчета.Скопировать(, "Поле");
	ИндексПолейОтчета.Свернуть("Поле");

	ПоляОтчета = ИндексПолейОтчета.ВыгрузитьКолонку("Поле");

	Для Каждого ПолеОтчета Из ПоляОтчета Цикл

		ОписаниеПоля = Настройки.ДоступныеПоляВыбора.НайтиПоле(ПолеОтчета);

		Если ОписаниеПоля = Неопределено Тогда
			ОписаниеПоля = Настройки.ДоступныеПоляГруппировок.НайтиПоле(ПолеОтчета);
		КонецЕсли;

		Если ОписаниеПоля <> Неопределено Тогда
			ОписаниеПолей.Добавить(ОписаниеПоля);
		КонецЕсли;

	КонецЦикла;

	Возврат ОписаниеПолей;

КонецФункции

&НаКлиенте
Процедура ПрименитьЗначениеУниверсальногоПоиска(ВариантыПоиска)

	ЭтоПользовательскийПоиск = Ложь;

	Если Не ЗначениеУниверсальногоПоискаПримененоКПараметрам(ВариантыПоиска, ЭтоПользовательскийПоиск) Тогда
		ПрименитьЗначениеУниверсальногоПоискаКОтборам(ВариантыПоиска, ЭтоПользовательскийПоиск);
	КонецЕсли;

	КомпоновщикНастроек = Отчет.КомпоновщикНастроек;

	Если Не ЭтоПользовательскийПоиск Тогда
		ВариантБылМодифицирован = ВариантМодифицирован;
		КомпоновщикНастроек.Настройки.ДополнительныеСвойства.Вставить("ОтчетИнициализирован", Ложь);
		ВариантМодифицирован = ВариантБылМодифицирован;

		РезультатНастройки = Новый Структура;
		РезультатНастройки.Вставить("КомпоновщикНастроекКД", КомпоновщикНастроек);
		РезультатНастройки.Вставить("ПользовательскиеНастройкиМодифицированы", Истина);
		ПодключитьОбработчикОжидания("ОбновитьЭлементыФормыНастроекОтложенно", 0.1, Истина);
	КонецЕсли;

	Если НастройкиОтчета.СвойстваРезультата.ВремяФормирования <= 5 Тогда
		ОчиститьСообщения();
		ПодключитьОбработчикОжидания("Сформировать", 0.1, Истина);
	Иначе
		ОтчетыКлиентСервер.ОповеститьОИзмененииНастроек(ЭтотОбъект);
	КонецЕсли;

	СброситьУниверсальныйПоиск();

КонецПроцедуры

&НаКлиенте
Функция ЗначениеУниверсальногоПоискаПримененоКПараметрам(ВариантыПоиска, ЭтоПользовательскийПоиск)

	КомпоновщикНастроек = Отчет.КомпоновщикНастроек;
	ПараметрыДанных = КомпоновщикНастроек.Настройки.ПараметрыДанных;

	ПолеПараметра = Неопределено;
	ПодходящийВариантПоиска = Неопределено;

	Для Каждого ВариантПоиска Из ВариантыПоиска Цикл

		ПолеПараметра = ПараметрыДанных.ДоступныеПоляПараметров.НайтиПоле(ВариантПоиска.ЛевоеЗначение);
		Если ПолеПараметра <> Неопределено Тогда
			ПодходящийВариантПоиска = ВариантПоиска;
			Прервать;
		КонецЕсли;

	КонецЦикла;

	Если ПолеПараметра = Неопределено Тогда
		Возврат Ложь;
	КонецЕсли;

	ОписаниеИмениПоляПараметра = СтрРазделить(ПолеПараметра.Поле, ".");
	ОписаниеИмениПараметра = Новый Массив;

	Для Индекс = 1 По ОписаниеИмениПоляПараметра.ВГраница() Цикл
		ОписаниеИмениПараметра.Добавить(ОписаниеИмениПоляПараметра[Индекс]);
	КонецЦикла;

	ИмяПараметра = СтрСоединить(ОписаниеИмениПараметра, ".");
	НайденныйПараметр = ПараметрыДанных.Элементы.Найти(ИмяПараметра);

	Если НайденныйПараметр = Неопределено Тогда
		Возврат Ложь;
	КонецЕсли;

	ОписаниеПараметра = ПараметрыДанных.ДоступныеПараметры.НайтиПараметр(НайденныйПараметр.Параметр);

	Если ОписаниеПараметра.ДоступенСписокЗначений Тогда
		НайденныйПараметр.Значение = ОтчетыКлиентСервер.ЗначенияСписком(ПодходящийВариантПоиска.ПравоеЗначение);
	Иначе
		НайденныйПараметр.Значение = ПодходящийВариантПоиска.ПравоеЗначение;
	КонецЕсли;

	НайденныйПараметр.Использование = Истина;

	ЭтоПользовательскийПоиск = ЗначениеЗаполнено(НайденныйПараметр.ИдентификаторПользовательскойНастройки);

	Если Не ЭтоПользовательскийПоиск Тогда
		НайденныйПараметр.ИдентификаторПользовательскойНастройки = Строка(Новый УникальныйИдентификатор);
	КонецЕсли;

	НайденныйПараметр.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.БыстрыйДоступ;

	ПользовательскийПараметр = КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(
		НайденныйПараметр.ИдентификаторПользовательскойНастройки);

	ПользовательскийПараметр.Значение = НайденныйПараметр.Значение;
	ПользовательскийПараметр.Использование = НайденныйПараметр.Использование;

	Возврат Истина;

КонецФункции

&НаКлиенте
Процедура ПрименитьЗначениеУниверсальногоПоискаКОтборам(ВариантыПоиска, ЭтоПользовательскийПоиск)

	КомпоновщикНастроек = Отчет.КомпоновщикНастроек;
	Фильтры = КомпоновщикНастроек.Настройки.Отбор;
	Фильтр = Неопределено;
	ПодходящийВариантПоиска = ?(ВариантыПоиска.Количество() = 0, Неопределено, ВариантыПоиска[0]);

	Для Каждого ВариантПоиска Из ВариантыПоиска Цикл

		Фильтр = ВариантыОтчетовСлужебныйКлиентСервер.ФильтрРазделаОтчета(Фильтры, ВариантПоиска.ЛевоеЗначение);

		Если Фильтр <> Неопределено Тогда

			ПодходящийВариантПоиска = ВариантПоиска;
			Прервать;

		КонецЕсли;

	КонецЦикла;

	Если ПодходящийВариантПоиска = Неопределено Тогда
		Возврат;
	КонецЕсли;

	Если Фильтр = Неопределено Тогда

		Фильтр = Фильтры.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
		Фильтр.ЛевоеЗначение = ПодходящийВариантПоиска.ЛевоеЗначение;

	КонецЕсли;

	ЭтоПользовательскийПоиск = ЗначениеЗаполнено(Фильтр.ИдентификаторПользовательскойНастройки);

	Если Не ЭтоПользовательскийПоиск Тогда

		Фильтр.ИдентификаторПользовательскойНастройки = Строка(Новый УникальныйИдентификатор);
		УточнитьСвойстваФильтра(Фильтр, ПодходящийВариантПоиска);

	КонецЕсли;

	Фильтр.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.БыстрыйДоступ;

	ПользовательскийФильтр = КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(
		Фильтр.ИдентификаторПользовательскойНастройки);

	УточнитьСвойстваФильтра(ПользовательскийФильтр, ПодходящийВариантПоиска);

КонецПроцедуры

&НаКлиенте
Процедура УточнитьСвойстваФильтра(Фильтр, Поиск)

	Если ТипЗнч(Фильтр) <> Тип("ЭлементОтбораКомпоновкиДанных") Тогда
		Возврат;
	КонецЕсли;

	Значения = ОтчетыКлиентСервер.ЗначенияСписком(Фильтр.ПравоеЗначение);

	Если Значения.НайтиПоЗначению(Поиск.ПравоеЗначение) = Неопределено Тогда
		Значения.Добавить(Поиск.ПравоеЗначение);
	КонецЕсли;

	Если Фильтр.Использование И Фильтр.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно 
		И Поиск.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно И Значения.Количество() > 1 Тогда

		Фильтр.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке;
		Фильтр.ПравоеЗначение = Значения;

	ИначеЕсли Фильтр.Использование И Фильтр.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке 
		И Поиск.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно Тогда

		Фильтр.ПравоеЗначение = Значения;

	ИначеЕсли Фильтр.Использование И Фильтр.ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавно 
		И Поиск.ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавно И Значения.Количество() > 1 Тогда

		Фильтр.ВидСравнения = ВидСравненияКомпоновкиДанных.НеВСписке;
		Фильтр.ПравоеЗначение = Значения;

	ИначеЕсли Фильтр.Использование И Фильтр.ВидСравнения = ВидСравненияКомпоновкиДанных.НеВСписке 
		И Поиск.ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавно Тогда

		Фильтр.ПравоеЗначение = Значения;

	Иначе
		Фильтр.Использование = Поиск.Использование;
		Фильтр.ВидСравнения = Поиск.ВидСравнения;
		Фильтр.ПравоеЗначение = Поиск.ПравоеЗначение;
	КонецЕсли;

КонецПроцедуры

#КонецОбласти

#Область УровниГруппировок

&НаСервере
Процедура ИнициализироватьМенюУровнейГруппировок()

	АдресИндексаСтруктурыОтчета = НастройкиОтчета.СвойстваРезультата.АдресИндексаСтруктурыОтчета;
	ИндексСтруктурыОтчета = Неопределено;

	Если ЭтоАдресВременногоХранилища(АдресИндексаСтруктурыОтчета) Тогда
		ИндексСтруктурыОтчета = ПолучитьИзВременногоХранилища(АдресИндексаСтруктурыОтчета);
	КонецЕсли;

	ОчиститьМенюУровнейГруппировок();
	ЗаполнитьМенюУровнейГруппировок(ИндексСтруктурыОтчета);

	УстановитьДоступностьМенюУровнейГруппировок();

КонецПроцедуры

&НаСервере
Процедура ОчиститьМенюУровнейГруппировок()

	Кнопки = Элементы.ГруппаУровниГруппировок.ПодчиненныеЭлементы;
	Индекс = Кнопки.Количество() - 1;

	Пока Индекс >= 0 Цикл

		Кнопка = Кнопки[Индекс];
		Индекс = Индекс - 1;

		Если Кнопка = Элементы.ПоказатьУровеньГруппировок Тогда
			Продолжить;
		КонецЕсли;

		ИмяДополнительнойКнопки = Кнопка.Имя + "Еще";
		ДополнительнаяКнопка = Элементы.Найти(ИмяДополнительнойКнопки);

		Если ДополнительнаяКнопка <> Неопределено Тогда
			Элементы.Удалить(ДополнительнаяКнопка);
		КонецЕсли;

		ИмяКнопкиКонтекстного = Кнопка.Имя + "КонтекстноеМеню";
		КнопкаКонтекстногоМеню = Элементы.Найти(ИмяКнопкиКонтекстного);

		Если КнопкаКонтекстногоМеню <> Неопределено Тогда
			Элементы.Удалить(КнопкаКонтекстногоМеню);
		КонецЕсли;

		Команда = Команды.Найти(Кнопка.Имя);

		Если Команда <> Неопределено Тогда
			Команды.Удалить(Команда);
		КонецЕсли;

		Элементы.Удалить(Кнопка);

	КонецЦикла;

КонецПроцедуры

&НаСервере
Процедура ЗаполнитьМенюУровнейГруппировок(ИндексСтруктурыОтчета)

	Если ОтчетТабличныйДокумент.КоличествоУровнейГруппировокСтрок() = 0 Тогда
		Возврат;
	КонецЕсли;

	Если ИндексСтруктурыОтчета = Неопределено Или ИндексСтруктурыОтчета.Количество() = 0 Тогда
		ИндексСтруктурыОтчета = ВариантыОтчетовСлужебный.НовыйИндексСтруктурыОтчета();
		КоличествоРазделов = 999;
	Иначе
		КоличествоРазделов = ИндексСтруктурыОтчета[0].КоличествоРазделов;
	КонецЕсли;

	Если КоличествоРазделов = 1 Тогда
		СвойстваМеню = СвойстваМенюУровнейГруппировокПростогоОтчета(ИндексСтруктурыОтчета);
	Иначе
		СвойстваМеню = СвойстваМенюУровнейГруппировокСложногоОтчета(ИндексСтруктурыОтчета);
	КонецЕсли;

	Для Каждого Свойства Из СвойстваМеню Цикл

		Команда = Команды.Добавить(Свойства.ИмяКоманды);
		Команда.Заголовок = Свойства.ПредставлениеУровняГруппировки;
		Команда.Действие = "Подключаемый_ПоказатьУровеньГруппировок";

		Кнопка = Элементы.Добавить(Свойства.ИмяКоманды, Тип("КнопкаФормы"), Элементы.ГруппаУровниГруппировок);
		Кнопка.Вид = ВидКнопкиФормы.КнопкаКоманднойПанели;
		Кнопка.ИмяКоманды = Свойства.ИмяКоманды;
		Кнопка.Заголовок = Свойства.ПредставлениеУровняГруппировки;
		Кнопка.ПоложениеВКоманднойПанели = ПоложениеКнопкиВКоманднойПанели.ВКоманднойПанели;
		
		// Подменю Еще.
		Кнопка = Элементы.Добавить(Свойства.ИмяКоманды + "Еще", Тип("КнопкаФормы"), Элементы.ГруппаУровниГруппировокЕще);
		Кнопка.Вид = ВидКнопкиФормы.КнопкаКоманднойПанели;
		Кнопка.ИмяКоманды = Свойства.ИмяКоманды;
		Кнопка.Заголовок = Свойства.ПредставлениеУровняГруппировки;
		Кнопка.ПоложениеВКоманднойПанели = ПоложениеКнопкиВКоманднойПанели.ВДополнительномПодменю;
		
		// Контекстное меню отчета.
		КнопкаКонтекстногоМеню = Элементы.Добавить(Свойства.ИмяКоманды + "КонтекстноеМеню", Тип("КнопкаФормы"),
			Элементы.ГруппаУровниГруппировокКонтекстноеМеню);
		КнопкаКонтекстногоМеню.Вид = ВидКнопкиФормы.КнопкаКоманднойПанели;
		КнопкаКонтекстногоМеню.ИмяКоманды = Свойства.ИмяКоманды;
		КнопкаКонтекстногоМеню.Заголовок = Свойства.ПредставлениеУровняГруппировки;

	КонецЦикла;

КонецПроцедуры

&НаСервере
Функция СвойстваМенюУровнейГруппировокСложногоОтчета(ИндексСтруктурыОтчета)

	СвойстваМеню = СвойстваМенюИзСтруктурыОтчета(ИндексСтруктурыОтчета);

	КоличествоУровнейГруппировок = ОтчетТабличныйДокумент.КоличествоУровнейГруппировокСтрок();
	Для УровеньГруппировки = 1 По КоличествоУровнейГруппировок Цикл

		Свойства = СвойстваМеню.Добавить();
		Свойства.ИмяКоманды = Элементы.ПоказатьУровеньГруппировок.Имя + УровеньГруппировки;
		Свойства.УровеньГруппировки = УровеньГруппировки;
		Свойства.ПредставлениеУровняГруппировки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Уровня %1'"), УровеньГруппировки);

	КонецЦикла;

	СвойстваМеню.Сортировать("УровеньГруппировки");
	Возврат СвойстваМеню;

КонецФункции

&НаСервере
Функция СвойстваМенюУровнейГруппировокПростогоОтчета(ИндексСтруктурыОтчета)

	ПоляСИерархическойГруппировкой = ПоляОтчетаСИерархическойГруппировкой(ИндексСтруктурыОтчета);

	Если ПоляСИерархическойГруппировкой.Количество() > 1 Тогда
		Возврат СвойстваМенюУровнейГруппировокСложногоОтчета(ИндексСтруктурыОтчета);
	КонецЕсли;

	КоличествоУровнейГруппировок = ОтчетТабличныйДокумент.КоличествоУровнейГруппировокСтрок();

	ГруппировкиОтчета = ГруппировкиОтчетаСУчетомПоляСИерархическойГруппировкой(
		ИндексСтруктурыОтчета, ПоляСИерархическойГруппировкой, КоличествоУровнейГруппировок);

	СвойстваМеню = СвойстваМенюИзСтруктурыОтчета(ИндексСтруктурыОтчета);
	Для Индекс = 0 По Мин(ГруппировкиОтчета.Количество(), КоличествоУровнейГруппировок) - 1 Цикл

		УровеньГруппировки = Индекс + 1;

		Свойства = СвойстваМеню.Добавить();
		Свойства.ПредставлениеУровняГруппировки = ГруппировкиОтчета[Индекс].ПредставлениеГруппировки;
		Свойства.ИмяКоманды = Элементы.ПоказатьУровеньГруппировок.Имя + УровеньГруппировки;
		Свойства.УровеньГруппировки = УровеньГруппировки;

	КонецЦикла;

	СвойстваМеню.Сортировать("УровеньГруппировки");
	Возврат СвойстваМеню;

КонецФункции

// Параметры:
//  ИндексСтруктурыОтчета - см. ВариантыОтчетовСлужебный.НовыйИндексСтруктурыОтчета 
// 
// Возвращаемое значение:
//  ТаблицаЗначений:
//    * ИмяКоманды - Строка
//    * УровеньГруппировки - Число
//    * ПредставлениеУровняГруппировки - Строка
//
&НаСервереБезКонтекста
Функция СвойстваМенюИзСтруктурыОтчета(ИндексСтруктурыОтчета)

	СвойстваМеню = ИндексСтруктурыОтчета.СкопироватьКолонки("ПорядокГруппировки, ПредставлениеГруппировки"); // ТаблицаЗначений

	СвойстваМеню.Колонки.Вставить(1, "ИмяКоманды", Новый ОписаниеТипов("Строка"));

	Колонка = СвойстваМеню.Колонки.Найти("ПорядокГруппировки"); // КолонкаТаблицыЗначений
	Колонка.Имя = "УровеньГруппировки";

	Колонка = СвойстваМеню.Колонки.Найти("ПредставлениеГруппировки"); // КолонкаТаблицыЗначений
	Колонка.Имя = "ПредставлениеУровняГруппировки";

	Возврат СвойстваМеню;

КонецФункции

&НаСервере
Функция ПоляОтчетаСИерархическойГруппировкой(ИндексСтруктурыОтчета)

	Поиск = Новый Структура;
	Поиск.Вставить("ИспользуетсяВПоляхГруппировки", Истина);
	Поиск.Вставить("ТипГруппировки", ТипГруппировкиКомпоновкиДанных.Иерархия);

	Возврат ИндексСтруктурыОтчета.Скопировать(Поиск);

КонецФункции

&НаСервере
Функция ГруппировкиОтчетаСУчетомПоляСИерархическойГруппировкой(ИндексСтруктурыОтчета, ПоляСИерархическойГруппировкой,
	КоличествоУровнейГруппировок)

	ГруппировкиОтчета = ИндексСтруктурыОтчета.Скопировать(); // ТаблицаЗначений

	Индекс = ГруппировкиОтчета.Количество() - 1;

	Пока Индекс >= 0 Цикл

		Если СтрНайти(ГруппировкиОтчета[Индекс].ИдентификаторГруппировки, "/column/") > 0 Тогда
			ГруппировкиОтчета.Удалить(Индекс);
		КонецЕсли;

		Индекс = Индекс - 1;

	КонецЦикла;

	ГруппировкиОтчета.Свернуть("ПорядокГруппировки, ПредставлениеГруппировки");

	КолонкиГруппировкиОтчета = ГруппировкиОтчета.Колонки; // КоллекцияКолонокТаблицыЗначений
	КолонкиГруппировкиОтчета.Добавить("Уровень", Новый ОписаниеТипов("Число"));

	ГруппировкиОтчета.Сортировать("ПорядокГруппировки");

	КоличествоУровнейПоляСИерархическойГруппировкой = КоличествоУровнейГруппировок - ГруппировкиОтчета.Количество();

	Если ПоляСИерархическойГруппировкой.Количество() <> 1 Или КоличествоУровнейПоляСИерархическойГруппировкой = 0 Тогда
		Возврат ГруппировкиОтчета;
	КонецЕсли;

	Поиск = Новый Структура("ПорядокГруппировки, ПредставлениеГруппировки");
	ЗаполнитьЗначенияСвойств(Поиск, ПоляСИерархическойГруппировкой[0]);

	НайденнаяГруппировка = ГруппировкиОтчета.НайтиСтроки(Поиск)[0];
	ИндексНайденнойГруппировки = ГруппировкиОтчета.Индекс(НайденнаяГруппировка);

	ШаблонПредставленияГруппировки = НСтр("ru = '%1 - уровень %2'");
	УровеньПоляСИерархическойГруппировкой = 0;

	Пока КоличествоУровнейПоляСИерархическойГруппировкой > 0 Цикл

		УровеньПоляСИерархическойГруппировкой = УровеньПоляСИерархическойГруппировкой + 1;

		ДополнительнаяГруппировка = ГруппировкиОтчета.Вставить(ИндексНайденнойГруппировки);
		ЗаполнитьЗначенияСвойств(ДополнительнаяГруппировка, НайденнаяГруппировка);

		ДополнительнаяГруппировка.Уровень = УровеньПоляСИерархическойГруппировкой;

		ДополнительнаяГруппировка.ПредставлениеГруппировки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			ШаблонПредставленияГруппировки, ДополнительнаяГруппировка.ПредставлениеГруппировки,
			УровеньПоляСИерархическойГруппировкой);

		КоличествоУровнейПоляСИерархическойГруппировкой = КоличествоУровнейПоляСИерархическойГруппировкой - 1;

	КонецЦикла;

	УровеньПоляСИерархическойГруппировкой = УровеньПоляСИерархическойГруппировкой + 1;

	НайденнаяГруппировка.Уровень = УровеньПоляСИерархическойГруппировкой;

	НайденнаяГруппировка.ПредставлениеГруппировки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		ШаблонПредставленияГруппировки, НайденнаяГруппировка.ПредставлениеГруппировки,
		УровеньПоляСИерархическойГруппировкой);

	ГруппировкиОтчета.Сортировать("ПорядокГруппировки, Уровень");

	Возврат ГруппировкиОтчета;

КонецФункции

&НаСервере
Процедура УстановитьДоступностьМенюУровнейГруппировок()

	МенюЗаполнено = (Элементы.ГруппаУровниГруппировок.ПодчиненныеЭлементы.Количество() > 1);

	Элементы.ПоказатьУровеньГруппировок.Видимость = Не МенюЗаполнено;
	Элементы.ПоказатьУровеньГруппировокЕще.Видимость = Не МенюЗаполнено;
	Элементы.ПоказатьУровеньГруппировокКонтекстноеМеню.Видимость = Не МенюЗаполнено;

	Элементы.ГруппаУровниГруппировок.Видимость = МенюЗаполнено;
	Элементы.ГруппаУровниГруппировокЕще.Видимость = МенюЗаполнено;
	Элементы.ГруппаУровниГруппировокКонтекстноеМеню.Видимость = МенюЗаполнено;

КонецПроцедуры

&НаКлиенте
Процедура ПоказатьВыбранныйУровеньГруппировок(УровеньГруппировки = Неопределено)

	Если УровеньГруппировки = Неопределено Тогда
		УровеньГруппировки = ?(РежимРасшифровки, НеопределенныйУровеньГруппировок(), ВыбранныйУровеньГруппировок);
	КонецЕсли;

	Индекс = УровеньГруппировки - 1;
	Граница = ОтчетТабличныйДокумент.КоличествоУровнейГруппировокСтрок() - 1;

	Пока Граница > Индекс Цикл

		ОтчетТабличныйДокумент.ПоказатьУровеньГруппировокСтрок(Граница);
		Граница = Граница - 1;

	КонецЦикла;

	ОтчетТабличныйДокумент.ПоказатьУровеньГруппировокСтрок(Индекс);

	ВыбранныйУровеньГруппировок = УровеньГруппировки;

	ЭталонноеМеню = Элементы.ГруппаУровниГруппировок;
	ЭталоннаяКнопка = Элементы.ПоказатьУровеньГруппировок;

	ОбластиВыводаМеню = Новый Соответствие;
	ОбластиВыводаМеню.Вставить(ЭталонноеМеню, ЭталоннаяКнопка);
	ОбластиВыводаМеню.Вставить(Элементы.ГруппаУровниГруппировокЕще, Элементы.ПоказатьУровеньГруппировокЕще);
	ОбластиВыводаМеню.Вставить(Элементы.ГруппаУровниГруппировокКонтекстноеМеню,
		Элементы.ПоказатьУровеньГруппировокКонтекстноеМеню);

	Для Каждого Область Из ОбластиВыводаМеню Цикл

		Кнопки = Область.Ключ.ПодчиненныеЭлементы;
		Для Каждого Кнопка Из Кнопки Цикл
			Кнопка.Пометка = Ложь;
		КонецЦикла;

		ИмяКнопки = ЭталоннаяКнопка.Имя + УровеньГруппировки + СтрЗаменить(Область.Значение.Имя, ЭталоннаяКнопка.Имя, "");
		Кнопка = Кнопки.Найти(ИмяКнопки);
		Если Кнопка <> Неопределено Тогда
			Кнопка.Пометка = Истина;
		КонецЕсли;

	КонецЦикла;

	ПодключитьОбработчикОжидания("СохранитьВыбранныйУровеньГруппировокОтложено", 0.1, Истина);

КонецПроцедуры

&НаКлиенте
Процедура СохранитьВыбранныйУровеньГруппировокОтложено()

	Если Не ВариантыОтчетовСлужебныйКлиентСервер.РежимВариантаОтчета(КлючТекущегоВарианта) Тогда
		КлючНастроек = КлючНастроекВариантаОтчета(НастройкиОтчета.ПолноеИмя, КлючТекущегоВарианта);
		СохранитьВыбранныйУровеньГруппировок(КлючНастроек, ВыбранныйУровеньГруппировок, РежимРасшифровки);
	КонецЕсли;

КонецПроцедуры

&НаСервереБезКонтекста
Процедура СохранитьВыбранныйУровеньГруппировок(КлючХраненияЗначения, ВыбранныйУровеньГруппировок, РежимРасшифровки)

	Если РежимРасшифровки Тогда
		Возврат;
	КонецЕсли;

	ОбщегоНазначения.ХранилищеНастроекДанныхФормСохранить(
		КлючХраненияЗначения, "ВыбранныйУровеньГруппировок", ВыбранныйУровеньГруппировок);

КонецПроцедуры

&НаСервереБезКонтекста
Процедура ВосстановитьВыбранныйУровеньГруппировок(КлючХраненияЗначения, ВыбранныйУровеньГруппировок, РежимРасшифровки)

	Если РежимРасшифровки Тогда
		Возврат;
	КонецЕсли;

	СохраненноеЗначение = ОбщегоНазначения.ХранилищеНастроекДанныхФормЗагрузить(
		КлючХраненияЗначения, "ВыбранныйУровеньГруппировок");

	Если ЗначениеЗаполнено(СохраненноеЗначение) Тогда
		ВыбранныйУровеньГруппировок = СохраненноеЗначение;
	Иначе
		ВыбранныйУровеньГруппировок = НеопределенныйУровеньГруппировок();
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура СброситьВыбранныйУровеньГруппировок()

	Если РежимРасшифровки Тогда
		Возврат;
	КонецЕсли;

	ВыбранныйУровеньГруппировок = НеопределенныйУровеньГруппировок();

	Для Каждого Элемент Из Элементы.ГруппаУровниГруппировок.ПодчиненныеЭлементы Цикл

		Если ТипЗнч(Элемент) = Тип("КнопкаФормы") Тогда
			Элемент.Пометка = Ложь;
		КонецЕсли;

	КонецЦикла;

	ПодключитьОбработчикОжидания("СохранитьВыбранныйУровеньГруппировокОтложено", 0.1, Истина);

КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Функция НеопределенныйУровеньГруппировок()
	Возврат 999;
КонецФункции

#КонецОбласти

#Область ВыводЗаголовковНастроек

&НаСервереБезКонтекста
Процедура СохранитьСостояниеОпцииВыводитьЗаголовкиНастроек(КлючХраненияЗначения, ВыводитьЗаголовкиНастроек,
	РежимРасшифровки)

	Если РежимРасшифровки Тогда
		Возврат;
	КонецЕсли;

	ОбщегоНазначения.ХранилищеНастроекДанныхФормСохранить(
		КлючХраненияЗначения, "ВыводитьЗаголовкиНастроек", ВыводитьЗаголовкиНастроек);

КонецПроцедуры

&НаСервереБезКонтекста
Процедура ВосстановитьСостояниеОпцииВыводитьЗаголовкиНастроек(КлючХраненияЗначения, ВыводитьЗаголовкиНастроек,
	РежимРасшифровки)

	Если РежимРасшифровки Тогда
		Возврат;
	КонецЕсли;

	СохраненноеЗначение = ОбщегоНазначения.ХранилищеНастроекДанныхФормЗагрузить(
		КлючХраненияЗначения, "ВыводитьЗаголовкиНастроек");

	ВыводитьЗаголовкиНастроек = СохраненноеЗначение = Неопределено Или СохраненноеЗначение = Истина;

КонецПроцедуры

#КонецОбласти

#Область СохранениеРезультатаОтчета

&НаКлиенте
Процедура СохранитьОтчетЗавершение(РасширениеПодключено, ДополнительныеПараметры) Экспорт

	Контекст = Новый Структура;
	Контекст.Вставить("ИндексФорматовСохраненияОтчета", Новый Соответствие);

	Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
	Диалог.Фильтр = ДоступныеФорматыСохраненияОтчета(Контекст.ИндексФорматовСохраненияОтчета);
	Диалог.МножественныйВыбор = Ложь;
	Диалог.Заголовок = НСтр("ru = 'Сохранение результата отчета'");

	Обработчик = Новый ОписаниеОповещения("СохранитьОтчетПослеВыбораИмениФайла", ЭтотОбъект, Контекст);
	ФайловаяСистемаКлиент.ПоказатьДиалогВыбора(Обработчик, Диалог);

КонецПроцедуры

&НаКлиенте
Процедура СохранитьОтчетПослеВыбораИмениФайла(Результат, Контекст) Экспорт

	Если ТипЗнч(Результат) = Тип("Массив") И Результат.Количество() > 0 Тогда
		ПолноеИмяФайлаОтчета = Результат[0];
	ИначеЕсли ТипЗнч(Результат) = Тип("Строка") Тогда
		ПолноеИмяФайлаОтчета = Результат;
	Иначе
		Возврат;
	КонецЕсли;

	Если Не ЗначениеЗаполнено(ПолноеИмяФайлаОтчета) Тогда
		Контекст.Вставить("ПолноеИмяФайлаОтчета", ОбщегоНазначенияКлиентСервер.ЗаменитьНедопустимыеСимволыВИмениФайла(
			Заголовок));
		ОписаниеОповещенияОЗакрытии = Новый ОписаниеОповещения("ПослеВыбораФорматаСохранения", ЭтотОбъект, Контекст);
		СписокФорматов = СписокДоступныхФорматовСохраненияОтчета(Контекст.ИндексФорматовСохраненияОтчета);
		ФорматПоУмолчанию = СписокФорматов.НайтиПоЗначению("mxl");
		СписокФорматов.ПоказатьВыборЭлемента(ОписаниеОповещенияОЗакрытии, НСтр("ru='Выберите формат сохранения'"),
			ФорматПоУмолчанию);
	Иначе
		Контекст.Вставить("ПолноеИмяФайлаОтчета", ПолноеИмяФайлаОтчета);
		ВыбранныйЭлемент = Новый Структура("Значение");
		ПослеВыбораФорматаСохранения(ВыбранныйЭлемент, Контекст);
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура ПослеВыбораФорматаСохранения(ВыбранныйЭлемент, Контекст) Экспорт

	Если ВыбранныйЭлемент = Неопределено Тогда
		Возврат;
	КонецЕсли;

	ПолноеИмяФайлаОтчета = Контекст.ПолноеИмяФайлаОтчета;
	Если ВыбранныйЭлемент.Значение <> Неопределено Тогда
		ПолноеИмяФайлаОтчета = ПолноеИмяФайлаОтчета + "." + ВыбранныйЭлемент.Значение;
	КонецЕсли;

	Обработчик = Новый ОписаниеОповещения("СохранитьОтчетПослеСохраненияРезультатаОтчета", ЭтотОбъект,
		ПолноеИмяФайлаОтчета);

	ФорматыСохранения = ФорматыСохраненияОтчета(ПолноеИмяФайлаОтчета, Контекст.ИндексФорматовСохраненияОтчета);
	СвойстваРезультата = НастройкиОтчета.СвойстваРезультата; // см. ВариантыОтчетовСлужебный.СвойстваРезультатаОтчета

	РезультатОтчета = РезультатОтчетаДляСохранения(ОтчетТабличныйДокумент, СвойстваРезультата.Заголовки);
	РезультатОтчета.НачатьЗапись(Обработчик, ПолноеИмяФайлаОтчета, ФорматыСохранения);
КонецПроцедуры

&НаКлиенте
Процедура СохранитьОтчетПослеСохраненияРезультатаОтчета(Результат, ПолноеИмяФайлаОтчета) Экспорт

	Если Результат <> Истина Тогда
		Возврат;
	КонецЕсли;

	Обработчик = Новый ОписаниеОповещения("СохранитьОтчетПриВыбореИмениФайлаОтчета", ЭтотОбъект, ПолноеИмяФайлаОтчета);
	ПоказатьОповещениеПользователя(НСтр("ru = 'Отчет сохранен в файл'"), Обработчик, ПолноеИмяФайлаОтчета);

КонецПроцедуры

&НаКлиенте
Процедура СохранитьОтчетПриВыбореИмениФайлаОтчета(ПолноеИмяФайлаОтчета) Экспорт

	ФайловаяСистемаКлиент.ОткрытьФайл(ПолноеИмяФайлаОтчета);

КонецПроцедуры

&НаКлиенте
Функция ФорматыСохраненияОтчета(Знач ПолноеИмяФайлаОтчета, ИндексФорматовСохраненияОтчета)

	ОписаниеПолногоИмениФайла = СтрРазделить(ПолноеИмяФайлаОтчета, ПолучитьРазделительПути());
	ИмяФайлаОтчета = ОписаниеПолногоИмениФайла[ОписаниеПолногоИмениФайла.ВГраница()];

	ОписаниеИмениФайла = СтрРазделить(ИмяФайлаОтчета, ".");
	РасширениеФайлаОтчета = ОписаниеИмениФайла[ОписаниеИмениФайла.ВГраница()];

	Возврат ИндексФорматовСохраненияОтчета[РасширениеФайлаОтчета];

КонецФункции

&НаСервереБезКонтекста
Функция ДоступныеФорматыСохраненияОтчета(ИндексФорматовСохраненияОтчета)

	ДоступныеФорматы = Новый Массив;

	ФорматыСохранения = СтандартныеПодсистемыСервер.НастройкиФорматовСохраненияТабличногоДокумента();

	ФорматСохраненияTXT = ФорматыСохранения.Найти(ТипФайлаТабличногоДокумента.TXT, "ТипФайлаТабличногоДокумента");
	ФорматСохраненияANSITXT = ФорматыСохранения.Найти(ТипФайлаТабличногоДокумента.ANSITXT,
		"ТипФайлаТабличногоДокумента");

	Если ФорматСохраненияTXT <> Неопределено И ФорматСохраненияANSITXT <> Неопределено Тогда
		ФорматыСохранения.Удалить(ФорматСохраненияANSITXT);
	КонецЕсли;

	ТекущийФорматСохранения = Новый Массив;

	Для Каждого ФорматСохранения Из ФорматыСохранения Цикл

		РасширениеФорматаСохранения = "*." + ФорматСохранения.Расширение;
		ПредставлениеФорматаСохранения = СтрЗаменить(ФорматСохранения.Представление, "." + ФорматСохранения.Расширение,
			РасширениеФорматаСохранения);

		ТекущийФорматСохранения.Добавить(ПредставлениеФорматаСохранения);
		ТекущийФорматСохранения.Добавить(РасширениеФорматаСохранения);

		ДоступныеФорматы.Добавить(СтрСоединить(ТекущийФорматСохранения, "|"));

		ТекущийФорматСохранения.Очистить();

		ИндексФорматовСохраненияОтчета.Вставить(ФорматСохранения.Расширение,
			ФорматСохранения.ТипФайлаТабличногоДокумента);

	КонецЦикла;

	Возврат СтрСоединить(ДоступныеФорматы, "|");

КонецФункции

&НаСервереБезКонтекста
Функция РезультатОтчетаДляСохранения(ОтчетТабличныйДокумент, Заголовки)

	РезультатОтчета = СкопироватьТабличныйДокумент(ОтчетТабличныйДокумент);

	Для Каждого ИндексЗаголовка Из Заголовки Цикл

		СвойстваЗаголовка = ИндексЗаголовка.Значение;

		Если Не СвойстваЗаголовка.ПолеСортируется Тогда
			Продолжить;
		КонецЕсли;

		Область = РезультатОтчета.Область(ИндексЗаголовка.Ключ);
		Область.Картинка = Неопределено;

	КонецЦикла;

	Возврат РезультатОтчета;

КонецФункции

&НаСервереБезКонтекста
Функция СкопироватьТабличныйДокумент(ТабличныйДокумент)

	ПотокВПамяти = Новый ПотокВПамяти;
	ТабличныйДокумент.Записать(ПотокВПамяти);
	ПотокВПамяти.Перейти(0, ПозицияВПотоке.Начало);

	Результат = Новый ТабличныйДокумент;
	Результат.Прочитать(ПотокВПамяти, СпособЧтенияЗначенийТабличногоДокумента.Значение);

	Возврат Результат;

КонецФункции

&НаСервере
Процедура СохранитьСнимокОтчетаПользователя()

	РезультатОтчета = СкопироватьТабличныйДокумент(ОтчетТабличныйДокумент);

	РегистрыСведений.СнимкиОтчетов.СохранитьСнимокОтчетаПользователя(РезультатОтчета, НастройкиОтчета);

КонецПроцедуры

#КонецОбласти

////////////////////////////////////////////////////////////////////////////////
// Вызов сервера

&НаСервере
Процедура УстановитьВидимостьДоступность()

	ПоказыватьКомандыВыбораВариантов = ВариантыОтчетовСлужебныйКлиентСервер.РежимВариантаОтчета(КлючТекущегоВарианта)
		И НастройкиОтчета.РазрешеноВыбиратьВарианты;

	ПоказыватьКомандыИзмененияВарианта = ПоказыватьКомандыВыбораВариантов И НастройкиОтчета.РазрешеноИзменятьВарианты;
	КоличествоДоступныхНастроек = ОтчетыСервер.КоличествоДоступныхНастроек(Отчет.КомпоновщикНастроек);

	Элементы.ВсеНастройки.Видимость = ПоказыватьКомандыИзмененияВарианта Или КоличествоДоступныхНастроек.Обычных > 0;
	Элементы.ВсеНастройкиЕще.Видимость = Элементы.ВсеНастройки.Видимость;
	Элементы.ГруппаВариантыОтчета.Видимость = ПоказыватьКомандыВыбораВариантов;
	Элементы.ГруппаСохранениеВыборВариантаОтчета.Видимость = Не ОбщегоНазначения.РазделениеВключено()
		Или ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных();

	Элементы.ИзменитьСоставБыстрыхНастроек.Видимость = ПоказыватьКомандыИзмененияВарианта И Не ЭтоМобильныйКлиент;

	Если ЭтоМобильныйКлиент Тогда
		Элементы.Переместить(Элементы.ГруппаПоказатель, Элементы.ГруппаДляПоказателей);
	КонецЕсли;

	ЭтоПредопределенныйВариант = Не НастройкиОтчета.Пользовательский И ЗначениеЗаполнено(
		НастройкиОтчета.ПредопределенныйСсылка);

	РазрешеноСохранятьВариант = ПоказыватьКомандыИзмененияВарианта
		И Не НастройкиОтчета.РазрешеноВыбиратьИНастраиватьВариантыБезСохранения;

	ДоступноСохранятьТекущийВариант = ЗначениеЗаполнено(НастройкиОтчета.ВариантСсылка) И Не ЭтоПредопределенныйВариант;
	Если ДоступноСохранятьТекущийВариант И ОбщегоНазначения.ПодсистемаСуществует(
		"СтандартныеПодсистемы.УправлениеДоступом") Тогда
		МодульУправлениеДоступом = ОбщегоНазначения.ОбщийМодуль("УправлениеДоступом");
		Если Не МодульУправлениеДоступом.ИзменениеРазрешено(НастройкиОтчета.ВариантСсылка) Тогда
			ДоступноСохранятьТекущийВариант = Ложь;
		КонецЕсли;
	КонецЕсли;

	ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(
		Элементы, "СохранитьВариант", "Видимость", РазрешеноСохранятьВариант И ДоступноСохранятьТекущийВариант);
	ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(
		Элементы, "СохранитьВариантЕще", "Видимость", РазрешеноСохранятьВариант И ДоступноСохранятьТекущийВариант);
	ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(
		Элементы, "СохранитьВариантКак", "Видимость", РазрешеноСохранятьВариант);
	ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(
		Элементы, "СохранитьВариантКакЕще", "Видимость", РазрешеноСохранятьВариант);

	Элементы.ДругиеОтчеты.Видимость = НастройкиОтчета.РазрешеноВыбиратьВарианты И Не ЗначениеЗаполнено(КонтекстВарианта);
	Элементы.ДругиеОтчетыЕще.Видимость = Элементы.ДругиеОтчеты.Видимость;

	Элементы.ВыбратьВариант.Видимость = ПоказыватьКомандыВыбораВариантов;

	Элементы.ГруппаСнимкиОтчетов.Видимость = НастройкиОтчета.ИспользоватьСнимкиОтчетов;

	РазрешеноИспользоватьНастройки = ПоказыватьКомандыВыбораВариантов И КоличествоДоступныхНастроек.Итог > 0
		И ОбщегоНазначенияКлиентСервер.ЗначениеСвойстваЭлементаФормы(Элементы, "ВыбратьНастройки", "Видимость") = Истина;

	ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(
		Элементы, "ВыбратьНастройки", "Видимость", РазрешеноИспользоватьНастройки);
	ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(
		Элементы, "СохранитьНастройки", "Видимость", РазрешеноИспользоватьНастройки);
	ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(
		Элементы, "ПоделитьсяНастройками", "Видимость", РазрешеноИспользоватьНастройки И (ЭтоПредопределенныйВариант
		Или ВариантыОтчетов.ПолныеПраваНаВарианты() Или ЗначениеЗаполнено(НастройкиОтчета.ВариантСсылка)
		И ОбщегоНазначения.ЗначениеРеквизитаОбъекта(НастройкиОтчета.ВариантСсылка, "ТолькоДляАвтора") <> Истина));

	Если НастройкиОтчета.РазрешеноВыбиратьИНастраиватьВариантыБезСохранения Тогда
		ВариантМодифицирован = Ложь;
	КонецЕсли;

	Элементы.КомандыПанелиБыстрыхНастроек.Видимость = (КоличествоДоступныхНастроек.БыстрогоДоступа > 0);
	Элементы.ИзменитьСоставБыстрыхНастроекЕще.Видимость = Элементы.КомандыПанелиБыстрыхНастроек.Видимость;
	
	// Команды выбора вариантов.
	Если ВариантыПанелиКлючТекущегоВарианта <> КлючТекущегоВарианта Тогда
		ВариантыПанелиКлючТекущегоВарианта = КлючТекущегоВарианта;

		Если ПоказыватьКомандыВыбораВариантов Тогда
			ОбновитьКомандыВыбораВариантов();
		КонецЕсли;

		Если ПравоВывода Тогда
			КлючСохраненияПоложенияОкна = ОтчетыКлиентСервер.КлючУникальности(НастройкиОтчета.ПолноеИмя,
				КлючТекущегоВарианта);
			НастройкиОтчета.Печать.Вставить("КлючПараметровПечати", КлючСохраненияПоложенияОкна);
			ЗаполнитьЗначенияСвойств(ОтчетТабличныйДокумент, НастройкиОтчета.Печать);
		КонецЕсли;

		НавигационнаяСсылка = "";
		Если ЗначениеЗаполнено(НастройкиОтчета.ВариантСсылка) И Не НастройкиОтчета.Внешний
			И Не НастройкиОтчета.Контекстный Тогда
			НавигационнаяСсылка = ПолучитьНавигационнуюСсылку(НастройкиОтчета.ВариантСсылка);
		КонецЕсли;
	КонецЕсли;
	
	Элементы.ВосстановитьСтандартнуюСхему.Видимость = НастройкиОтчета.РазрешеноВосстанавливатьСтандартнуюСхему;
	Элементы.РедактироватьСхему.Видимость = НастройкиОтчета.РазрешеноРедактироватьСхему
		И Не ОбщегоНазначения.РазделениеВключено(); 
	Элементы.ЗагрузитьСхему.Видимость = НастройкиОтчета.РазрешеноЗагружатьСхему
		И Не ОбщегоНазначения.РазделениеВключено();

	УстановитьДоступностьМенюУровнейГруппировок();
	
	ОтчетНаименованиеТекущегоВарианта = СокрЛП(ОтчетНаименованиеТекущегоВарианта);
	Если ЗначениеЗаполнено(ОтчетНаименованиеТекущегоВарианта) Тогда
		Заголовок = ОтчетНаименованиеТекущегоВарианта;
	Иначе
		ОписаниеНастроекОтчета = ОписаниеНастроекОтчета(НастройкиОтчета);
		Заголовок = ОписаниеНастроекОтчета.Наименование;
	КонецЕсли;

	Если РежимРасшифровки Тогда
		Заголовок = Заголовок + " (" + НСтр("ru = 'Расшифровка'") + ")";
	КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ПроверитьДоступностьОбменаНастройкамиВарианта(МетаданныеОтчета)

	ОбменНастройкамиВариантаДоступен = ВариантыОтчетовСлужебныйКлиентСервер.РежимВариантаОтчета(КлючТекущегоВарианта)
		И ВариантыОтчетов.ОтчетПодключенКХранилищу(МетаданныеОтчета);

	Элементы.ГруппаОбменНастройкамиЕще.Видимость = ОбменНастройкамиВариантаДоступен;
	Элементы.ОбновитьВариантОтчетаИзФайла.Видимость = ОбменНастройкамиВариантаДоступен;
	Элементы.СохранитьВариантОтчетаВФайл.Видимость = ОбменНастройкамиВариантаДоступен;

КонецПроцедуры

&НаСервере
Процедура ЗагрузитьВариант(КлючВарианта, ОчиститьСтекНастроек = Истина)
	Если Не РежимРасшифровки И Не ВариантМодифицирован Тогда
		КлючОбъекта = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("%1/%2/ТекущиеПользовательскиеНастройки", 
			НастройкиОтчета.ПолноеИмя, КлючТекущегоВарианта);
		ОбщегоНазначения.ХранилищеСистемныхНастроекСохранить(	КлючОбъекта, "", 
			Отчет.КомпоновщикНастроек.ПользовательскиеНастройки);
	КонецЕсли;

	СохранитьДанныеВНастройкахНаСервере();

	РежимРасшифровки = Ложь;
	ВариантМодифицирован = Ложь;
	ПользовательскиеНастройкиМодифицированы = Ложь;
	НастройкиОтчета.ПрочитатьФлажокФормироватьСразуИзПользовательскихНастроек = Истина;

	ПоместитьВоВременноеХранилище(Неопределено, НастройкиОтчета.СвойстваРезультата.АдресИндексаСтруктурыОтчета);

	Если ОчиститьСтекНастроек Тогда
		СтекНастроек.Очистить();
	КонецЕсли;

	УстановитьТекущийВариант(КлючВарианта);
	ОтчетыКлиентСервер.ОтобразитьСостояниеОтчета(	ЭтотОбъект, 
		НСтр("ru = 'Выбран другой вариант отчета. Нажмите ""Сформировать"" для получения отчета.'"),
		БиблиотекаКартинок.Информация32);
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// Сервер

&НаСервере
Процедура ОпределитьПоведениеВМобильномКлиенте()
	ЭтоМобильныйКлиент = ОбщегоНазначения.ЭтоМобильныйКлиент();
	Если Не ЭтоМобильныйКлиент Тогда
		Возврат;
	КонецЕсли;

	Элементы.КомандыИПоказатели.Заголовок = НСтр("ru = 'показатели'");
	Элементы.Переместить(Элементы.КомандыИПоказатели, ЭтотОбъект, Элементы.ПредопределенныеЭлементыНастроек);
	Элементы.ГруппаГлавное.Видимость = Ложь;
	Элементы.ГруппаНастройкиОтчета.Видимость = Ложь;
	Элементы.ГруппаРаботаВТаблице.Видимость = Ложь;
	Элементы.ГруппаВывод.Видимость = Ложь;
	Элементы.Редактирование.Видимость = Ложь;

	Элементы.ГруппаПоказатель.РастягиватьПоГоризонтали = Неопределено;
	Элементы.Показатель.Ширина = 0;

	Элементы.ПанельБыстрыхНастроек.Видимость = Ложь;
	Элементы.ГруппаКнопокМобильныйКлиент.Видимость = Истина;

	Элементы.КомандыИПоказатели.Видимость = Ложь;
	Элементы.СформироватьОтчет.КнопкаПоУмолчанию = Ложь;

КонецПроцедуры

&НаСервере
Функция КонтекстВариантаОтчета()
	Если РежимРасшифровки Тогда
		Возврат "";
	КонецЕсли;

	Если Не ПустаяСтрока(Параметры.КонтекстВарианта) Тогда
		Возврат Параметры.КонтекстВарианта;
	КонецЕсли;

	СвойстваИнтерфейса = СтрРазделить("ПараметрКоманды, Отбор", ", ", Ложь);
	Для Каждого СвойствоИнтерфейса Из СвойстваИнтерфейса Цикл

		ЗначениеСвойства = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Параметры, СвойствоИнтерфейса);
		Если ЗначениеСвойства = Неопределено Тогда
			Продолжить;
		КонецЕсли;

		Если ОбщегоНазначения.ЗначениеСсылочногоТипа(ЗначениеСвойства) Тогда
			Возврат ЗначениеСвойства.Метаданные().ПолноеИмя();

		ИначеЕсли ТипЗнч(ЗначениеСвойства) = Тип("Массив") И ЗначениеСвойства.Количество() > 0
			И ОбщегоНазначения.ЗначениеСсылочногоТипа(ЗначениеСвойства[0]) Тогда

			Возврат ЗначениеСвойства[0].Метаданные().ПолноеИмя();

		ИначеЕсли ТипЗнч(ЗначениеСвойства) = Тип("Структура") Тогда

			Для Каждого ЭлементСтруктуры Из ЗначениеСвойства Цикл
				ЗначениеЭлемента = ЭлементСтруктуры.Значение;
				Если ОбщегоНазначения.ЗначениеСсылочногоТипа(ЗначениеЭлемента) Тогда
					Возврат ЗначениеЭлемента.Метаданные().ПолноеИмя();
				ИначеЕсли ТипЗнч(ЗначениеЭлемента) = Тип("Массив") И ЗначениеЭлемента.Количество() > 0
					И ОбщегоНазначения.ЗначениеСсылочногоТипа(ЗначениеЭлемента[0]) Тогда
					Возврат ЗначениеЭлемента[0].Метаданные().ПолноеИмя();
				КонецЕсли;
			КонецЦикла;

		КонецЕсли;
	КонецЦикла;

	ОписаниеКоманды = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Параметры, "ОписаниеКоманды");
	Если ТипЗнч(ОписаниеКоманды) = Тип("Структура") Тогда

		ОписаниеТипаКонтекста = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ОписаниеКоманды, "ТипПараметра");
		ТипыКонтекста = ?(ТипЗнч(ОписаниеТипаКонтекста) = Тип("ОписаниеТипов"), ОписаниеТипаКонтекста.Типы(),
			Новый Массив);

		Если ТипыКонтекста.Количество() > 0 Тогда
			Возврат Метаданные.НайтиПоТипу(ТипыКонтекста[0]).ПолноеИмя();
		КонецЕсли;
	КонецЕсли;

	Возврат Неопределено;
КонецФункции

&НаСервере
Процедура УстановитьКлючНазначенияИспользования()
	Если ЗначениеЗаполнено(КлючНазначенияИспользования) Тогда
		Возврат;
	КонецЕсли;

	Если ЗначениеЗаполнено(Параметры.КлючНазначенияИспользования) Тогда
		КлючНазначенияИспользования = Параметры.КлючНазначенияИспользования;
	ИначеЕсли ЗначениеЗаполнено(КонтекстВарианта) Тогда
		КлючНазначенияИспользования = КонтекстВарианта + ?(ЗначениеЗаполнено(Параметры.КлючВарианта), ".", "")
			+ Параметры.КлючВарианта;
	КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура СохранитьПараметрыФормы()

	ФормаПараметры = ВариантыОтчетов.СохраняемыеПараметрыФормыОтчета(Параметры);
	ФормаПараметры.КлючНазначенияИспользования = КлючНазначенияИспользования;

КонецПроцедуры

&НаСервере
Процедура УстановитьКлючТекущегоВарианта(ОтчетПолноеИмя, ОтчетОбъект)
	ВариантыПанелиКлючТекущегоВарианта = ПустойКлючВарианта();

	Расшифровка = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Параметры, "Расшифровка");
	КлючТекущегоВариантаРасшифровки = "";
	Если ТипЗнч(Расшифровка) = Тип("ОписаниеОбработкиРасшифровкиКомпоновкиДанных") Тогда
		Настройки = ПолучитьИзВременногоХранилища(Расшифровка.Данные).Настройки;
		КлючТекущегоВариантаРасшифровки = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(
			Настройки.ДополнительныеСвойства, "КлючВарианта", "");
	КонецЕсли;

	Если ЗначениеЗаполнено(КлючТекущегоВариантаРасшифровки) Тогда
		КлючТекущегоВарианта = КлючТекущегоВариантаРасшифровки;
		Если Не ЗначениеЗаполнено(КлючНазначенияИспользования) Тогда
			КлючНазначенияИспользования = "Расшифровка";
		КонецЕсли;
	Иначе
		Если ЗначениеЗаполнено(КлючНазначенияИспользования) Тогда
			КлючОбъекта = ОтчетПолноеИмя + "/" + КлючНазначенияИспользования + "/КлючТекущегоВарианта";
		Иначе
			КлючОбъекта = ОтчетПолноеИмя + "/КлючТекущегоВарианта";
		КонецЕсли;

		КлючТекущегоВарианта = ОбщегоНазначения.ХранилищеСистемныхНастроекЗагрузить(КлючОбъекта, "");
	КонецЕсли;

	Если Не ЗначениеЗаполнено(КлючТекущегоВарианта) Или (ЗначениеЗаполнено(Параметры.КлючВарианта)
		И КлючТекущегоВарианта <> Параметры.КлючВарианта) Тогда

		Если ЗначениеЗаполнено(Параметры.КлючВарианта) Тогда
			КлючТекущегоВарианта = Параметры.КлючВарианта;

		ИначеЕсли ОтчетОбъект.СхемаКомпоновкиДанных <> Неопределено Тогда
			Для Каждого Вариант Из ОтчетОбъект.СхемаКомпоновкиДанных.ВариантыНастроек Цикл
				КлючТекущегоВарианта = Вариант.Имя;
				Прервать;
			КонецЦикла;
		КонецЕсли;

	КонецЕсли;
	
	// Сохраняется ключ контекстного варианты, который обычно исключен из интерфейса,
	//  т.е. Включен равен Ложь (см. Справочник.ПредопределенныеВариантыОтчетов.Включен = Ложь).
	Если ЗначениеЗаполнено(КонтекстВарианта) Тогда
		ВариантКонтекста = ?(ЗначениеЗаполнено(Параметры.КлючВарианта), Параметры.КлючВарианта, КлючТекущегоВарианта);
		ВариантыКонтекста.Добавить(ВариантКонтекста);
	КонецЕсли;

	Если ЗначениеЗаполнено(КонтекстВарианта) И ЗначениеЗаполнено(Параметры.КлючВарианта) 
		И Параметры.КлючВарианта <> КлючТекущегоВарианта Тогда 
		Параметры.КлючВарианта = Неопределено;
	КонецЕсли;
КонецПроцедуры

// Параметры:
//  ОтчетОбъект - ОтчетОбъект
//
// Возвращаемое значение:
//   см. ВариантыОтчетов.НастройкиФормыОтчета
//
&НаСервере
Функция НастройкиОтчета(ОтчетОбъект)

	Настройки = ВариантыОтчетов.НастройкиФормыОтчета(Параметры.Отчет, КлючТекущегоВарианта, ОтчетОбъект);
	Настройки.АдресСхемы = АдресСхемыОтчета(ОтчетОбъект);
	Настройки.Контекстный = ЗначениеЗаполнено(КонтекстВарианта);
	Настройки.Подсистема  = ФормаПараметры.Подсистема;
	Настройки.ИспользуемыеТаблицы = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Параметры, "ИспользуемыеТаблицы");
	Настройки.СобытияНастроек = СобытияНастроек();
	Настройки.ИспользоватьСнимкиОтчетов = ПравоДоступа("МобильныйКлиент", Метаданные);

	Возврат Настройки;
КонецФункции

// Параметры:
//  Описание - см. НастройкиОтчета
//
// Возвращаемое значение:
//   см. НастройкиОтчета
//
&НаКлиентеНаСервереБезКонтекста
Функция ОписаниеНастроекОтчета(Описание)

	Возврат Описание;

КонецФункции

&НаСервере
Функция АдресСхемыОтчета(ОтчетОбъект)
	АдресСхемы = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Параметры, "АдресСхемы", "");

	Расшифровка = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Параметры, "Расшифровка");

	Если ТипЗнч(Расшифровка) = Тип("ОписаниеОбработкиРасшифровкиКомпоновкиДанных") Тогда
		Настройки = ПолучитьИзВременногоХранилища(Расшифровка.Данные).Настройки;
		АдресСхемы = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Настройки.ДополнительныеСвойства, "АдресСхемы", "");
	КонецЕсли;

	ЭтоСхема = Ложь;
	Если ЭтоАдресВременногоХранилища(АдресСхемы) Тогда
		Схема = ПолучитьИзВременногоХранилища(АдресСхемы);
		ЭтоСхема = (ТипЗнч(Схема) = Тип("СхемаКомпоновкиДанных"));

		Если ЭтоСхема Тогда
			АдресСхемы = ПоместитьВоВременноеХранилище(Схема, УникальныйИдентификатор);
			Отчет.КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(АдресСхемы));
		КонецЕсли;
	КонецЕсли;

	Если Не ЭтоСхема Тогда
		АдресСхемы = ПоместитьВоВременноеХранилище(ОтчетОбъект.СхемаКомпоновкиДанных, УникальныйИдентификатор);
	КонецЕсли;

	Возврат АдресСхемы;
КонецФункции

#Область СобытияНастроек

&НаСервере
Функция СобытияНастроек()

	СобытияНастроек = Новый Соответствие;

	НайтиСобытияНастроек(Элементы.ОтчетТабличныйДокумент.КонтекстноеМеню, УточненияСобытийНастроек(), 
		СобытияНастроекИсключения(), СобытияНастроек);

	СобытияНастроек.Вставить("ФильтроватьИСформировать", НСтр("ru = 'Фильтровать...'"));
	СобытияНастроек.Вставить(ВариантыОтчетовСлужебныйКлиентСервер.ИмяСобытияФормыНастроек(), 
		НСтр("ru = 'Расширенная настройка'"));
	СобытияНастроек.Вставить(ВариантыОтчетовСлужебныйКлиентСервер.ИмяСобытияИзмененияСоставаБыстрыхНастроек(), 
		НСтр("ru = 'Изменение состава быстрых настроек'"));

	Возврат СобытияНастроек;

КонецФункции

&НаСервере
Функция УточненияСобытийНастроек()

	Префиксы = Новый Соответствие;
	Префиксы.Вставить("ОформитьЖелтым", НСтр("ru = 'Оформить желтым'"));
	Префиксы.Вставить("ОформитьКрасным", НСтр("ru = 'Оформить красным'"));
	Префиксы.Вставить("ОформитьЗеленым", НСтр("ru = 'Оформить зеленым'"));
	Префиксы.Вставить("ОформитьЕще", НСтр("ru = 'Оформить (еще)'"));

	Возврат Префиксы;

КонецФункции

&НаСервере
Функция СобытияНастроекИсключения()

	Исключения = Новый Массив;
	Исключения.Добавить("Открыть");
	Исключения.Добавить("РасшифроватьПоДетальнымЗаписям");
	Исключения.Добавить("Расшифровать");
	Исключения.Добавить("Подключаемый_ПоказатьУровеньГруппировок");
	Исключения.Добавить("ОтчетСкомпоноватьРезультат");

	Возврат Исключения;

КонецФункции

&НаСервере
Процедура НайтиСобытияНастроек(Меню, Уточнения, Исключения, СобытияНастроек)

	Для Каждого Элемент Из Меню.ПодчиненныеЭлементы Цикл

		Если ТипЗнч(Элемент) = Тип("ГруппаФормы") Тогда

			НайтиСобытияНастроек(Элемент, Уточнения, Исключения, СобытияНастроек);

		ИначеЕсли СобытияНастроек[Элемент.ИмяКоманды] = Неопределено 
			И Исключения.Найти(Элемент.ИмяКоманды) = Неопределено Тогда

			НайденнаяКоманда = Команды.Найти(Элемент.ИмяКоманды);
			Если НайденнаяКоманда = Неопределено Тогда
				Продолжить;
			КонецЕсли;

			ДействиеКоманды = ?(ЗначениеЗаполнено(НайденнаяКоманда.Действие), НайденнаяКоманда.Действие,
				НайденнаяКоманда.Имя);
			ПредставлениеДействия = Уточнения[ДействиеКоманды];

			Если ПредставлениеДействия = Неопределено Тогда
				ПредставлениеДействия = НайденнаяКоманда.Заголовок;
			КонецЕсли;

			СобытияНастроек.Вставить(ДействиеКоманды, ПредставлениеДействия);

		КонецЕсли;

	КонецЦикла;

КонецПроцедуры

#КонецОбласти

&НаСервере
Процедура УстановитьРазрешенияПользователя()

	ВидимостьКомандВариантовОтчетов = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(
		Параметры, "ВидимостьКомандВариантовОтчетов", Истина);

	Если НастройкиОтчета.РазрешеноВыбиратьИНастраиватьВариантыБезСохранения Тогда

		НастройкиОтчета.РазрешеноИзменятьВарианты = Истина;
		НастройкиОтчета.РазрешеноВыбиратьВарианты = Истина;

	ИначеЕсли Не ВидимостьКомандВариантовОтчетов Тогда

		НастройкиОтчета.РазрешеноИзменятьВарианты = Ложь;
		НастройкиОтчета.РазрешеноВыбиратьВарианты = Ложь;

	КонецЕсли;

	Если НастройкиОтчета.РазрешеноИзменятьВарианты И Не ВариантыОтчетовПовтИсп.ПравоДобавления() Тогда
		НастройкиОтчета.РазрешеноИзменятьВарианты = Ложь;
	КонецЕсли;

КонецПроцедуры

&НаСервере
Функция ДанныеЭлементаРасшифровки(Расшифровка)

	Возврат ВариантыОтчетовСлужебный.ДанныеЭлементаРасшифровки(ЭтотОбъект, Расшифровка);

КонецФункции

&НаСервере
Процедура ОбновитьЭлементыФормыНастроекНаСервере(ПараметрыОбновления = Неопределено)
	ЗагрузитьНастройкиВКомпоновщик(ПараметрыОбновления);

	ОтчетыСервер.ОбновитьЭлементыФормыНастроек(
		ЭтотОбъект, Элементы.КомпоновщикНастроекПользовательскиеНастройки, ПараметрыОбновления);

	Если ПараметрыОбновления.ИмяСобытия <> "ПослеФормирования" Тогда
		Переформировать = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ПараметрыОбновления, "Переформировать", Ложь);

		Если Переформировать И Не ПроверитьЗаполнение() Тогда

			ПараметрыОбновления.Переформировать = Ложь;

		ИначеЕсли Переформировать Тогда

			ОтчетыКлиентСервер.ОтобразитьСостояниеОтчета(
				ЭтотОбъект, НСтр("ru = 'Отчет формируется...'"), БиблиотекаКартинок.ДлительнаяОперация48);

		ИначеЕсли Не ОтчетСформирован И (ПараметрыОбновления.ВариантМодифицирован
			Или ПараметрыОбновления.ПользовательскиеНастройкиМодифицированы) Тогда

			ОтчетыКлиентСервер.ОповеститьОИзмененииНастроек(ЭтотОбъект);
		КонецЕсли;
	КонецЕсли;
	
	// Стандартный диалог не показывается если пользователю запрещено изменять варианты этого отчета.
	Если Не НастройкиОтчета.РазрешеноИзменятьВарианты Тогда
		ВариантМодифицирован = Ложь;
	КонецЕсли;

	ОтчетыСервер.ВосстановитьЗначенияОтборов(ЭтотОбъект);
	ОбновитьМенюПереходаМеждуИзменениямиНастроек();
	УстановитьВидимостьДоступность();
КонецПроцедуры

&НаСервере
Процедура ЗагрузитьНастройкиВКомпоновщик(ПараметрыЗагрузки)
	ПроверитьПараметрыЗагрузки(ПараметрыЗагрузки);

	ОтчетОбъект = РеквизитФормыВЗначение("Отчет");
	Если НастройкиОтчета.События.ПередЗаполнениемПанелиБыстрыхНастроек Тогда
		ОтчетОбъект.ПередЗаполнениемПанелиБыстрыхНастроек(ЭтотОбъект, ПараметрыЗагрузки);
	КонецЕсли;

	ДоступныеНастройки = ОтчетыСервер.ДоступныеНастройки(ПараметрыЗагрузки, НастройкиОтчета);

	СброситьНастройкиВарианта = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(
		ПараметрыЗагрузки, "СброситьНастройкиВарианта", Ложь);
	Если СброситьНастройкиВарианта Тогда
		ПараметрыЗагрузкиПередУстановкойТекущегоВарианта = ПараметрыЗагрузки;
		ЗагрузитьВариант(КлючТекущегоВарианта, Ложь);
		ПараметрыЗагрузкиПередУстановкойТекущегоВарианта = Неопределено;
	КонецЕсли;
	
	Если ПараметрыЗагрузкиПередУстановкойТекущегоВарианта <> Неопределено
	   И ПараметрыЗагрузкиПередУстановкойТекущегоВарианта.Свойство("СброситьПользовательскиеНастройки") Тогда
		ПараметрыЗагрузки.Вставить("СброситьПользовательскиеНастройки",
			ПараметрыЗагрузкиПередУстановкойТекущегоВарианта.СброситьПользовательскиеНастройки);
	КонецЕсли;

	ОтчетыСервер.СброситьПользовательскиеНастройки(ДоступныеНастройки, ПараметрыЗагрузки);

	ОтчетыСервер.ЗаполнитьДополнительныеСвойства(ОтчетОбъект, ДоступныеНастройки.Настройки, КлючТекущегоВарианта,
		НастройкиОтчета.КлючПредопределенногоВарианта, 
		?(ВариантыОтчетов.ДопустимоУстановитьКонтекст(ЭтотОбъект), КонтекстВарианта, ""), 
		?(ВариантыОтчетов.ДопустимоУстановитьКонтекст(ЭтотОбъект), ФормаПараметры.Отбор, Неопределено));

	Если ДоступныеНастройки.Настройки <> Неопределено И НастройкиОтчета.События.ПередЗагрузкойНастроекВКомпоновщик Тогда
		ОтчетОбъект.ПередЗагрузкойНастроекВКомпоновщик(ЭтотОбъект, НастройкиОтчета.КлючСхемы, КлючТекущегоВарианта, 
			ДоступныеНастройки.Настройки, ДоступныеНастройки.ПользовательскиеНастройки);
	КонецЕсли;

	НастройкиЗагружены = ОтчетыКлиентСервер.ЗагрузитьНастройки(Отчет.КомпоновщикНастроек, ДоступныеНастройки.Настройки, 
		ДоступныеНастройки.ПользовательскиеНастройки, ДоступныеНастройки.ФиксированныеНастройки);
	
	// Установка фиксированных отборов выполняется через компоновщик, т.к. в нем наиболее полная коллекция настроек.
	// В ПередЗагрузкой в параметрах могут отсутствовать те параметры, настройки которые не переопределялись.
	Если НастройкиЗагружены И ВариантыОтчетов.ДопустимоУстановитьКонтекст(ЭтотОбъект) 
		И ТипЗнч(ФормаПараметры.Отбор) = Тип("Структура") Тогда

		ОтчетыСервер.УстановитьФиксированныеОтборы(ФормаПараметры.Отбор, Отчет.КомпоновщикНастроек.Настройки,
			НастройкиОтчета);
	КонецЕсли;

	ФормаПараметры.ФиксированныеНастройки = Отчет.КомпоновщикНастроек.ФиксированныеНастройки;

	ДополнительныеСвойства = Отчет.КомпоновщикНастроек.Настройки.ДополнительныеСвойства;
	ДополнительныеСвойства.Вставить("ВариантНаименование", ОтчетНаименованиеТекущегоВарианта);

	ОтчетОбъект = РеквизитФормыВЗначение("Отчет");
	Если НастройкиОтчета.События.ПослеЗагрузкиНастроекВКомпоновщик Тогда
		ОтчетОбъект.ПослеЗагрузкиНастроекВКомпоновщик(Новый Структура);
	КонецЕсли;
	Если Не НастройкиОтчета.Пользовательский Тогда
		ОтчетОбъект.КомпоновщикНастроек.Настройки.ДополнительныеСвойства.Свойство("ВариантНаименование", 
			ОтчетНаименованиеТекущегоВарианта);
	КонецЕсли;

	ОтчетыСервер.УстановитьДоступныеЗначения(ОтчетОбъект, ЭтотОбъект);
	ОтчетыСервер.ИнициализироватьПредопределенныеПараметрыВывода(НастройкиОтчета, Отчет.КомпоновщикНастроек.Настройки,
		ОтчетыСервер.ТребуетсяСброситьПредопределенныеПараметрыВывода(ПараметрыЗагрузки));

	Если ПараметрыЗагрузки.ВариантМодифицирован Тогда
		ВариантМодифицирован = Истина;
	КонецЕсли;

	Если ПараметрыЗагрузки.ПользовательскиеНастройкиМодифицированы Тогда
		ПользовательскиеНастройкиМодифицированы = Истина;
	КонецЕсли;

	ДополнительныеСвойства = Отчет.КомпоновщикНастроек.Настройки.ДополнительныеСвойства;
	ДополнительныеСвойства.Вставить("КлючВарианта", КлючТекущегоВарианта);
	ДополнительныеСвойства.Вставить("ВариантНаименование", ОтчетНаименованиеТекущегоВарианта);
	ДополнительныеСвойства.Вставить("КонтекстВарианта", КонтекстВарианта);
	
	// Подготовка к предварительной инициализации компоновщика (используется при расшифровке).
	Если НастройкиОтчета.СхемаМодифицирована Тогда
		ДополнительныеСвойства.Вставить("АдресСхемы", НастройкиОтчета.АдресСхемы);
	КонецЕсли;

	Если ПараметрыЗагрузки.Свойство("ФормаНастроекРасширенныйРежим") Тогда
		НастройкиОтчета.ФормаНастроекРасширенныйРежим = ПараметрыЗагрузки.ФормаНастроекРасширенныйРежим;
	КонецЕсли;

	Если ПараметрыЗагрузки.Свойство("ФормаНастроекИмяСтраницы") Тогда
		НастройкиОтчета.ФормаНастроекИмяСтраницы = ПараметрыЗагрузки.ФормаНастроекИмяСтраницы;
	КонецЕсли;

	ОтчетыСервер.УстановитьУсловияОтборов(ПараметрыЗагрузки, Отчет.КомпоновщикНастроек);

	Если НастройкиОтчета.ПрочитатьФлажокФормироватьСразуИзПользовательскихНастроек Тогда
		НастройкиОтчета.ПрочитатьФлажокФормироватьСразуИзПользовательскихНастроек = Ложь;
		Элементы.ФормироватьСразу.Пометка = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(
			Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.ДополнительныеСвойства, "ФормироватьСразу",
			НастройкиОтчета.ФормироватьСразу);
	КонецЕсли;

КонецПроцедуры

&НаСервере
Процедура ПроверитьПараметрыЗагрузки(ПараметрыЗагрузки)
	Если ТипЗнч(ПараметрыЗагрузки) <> Тип("Структура") Тогда
		ПараметрыЗагрузки = Новый Структура;
	КонецЕсли;

	Если Не ПараметрыЗагрузки.Свойство("ИмяСобытия") Тогда
		ПараметрыЗагрузки.Вставить("ИмяСобытия", "");
	КонецЕсли;

	Если Не ПараметрыЗагрузки.Свойство("ВариантМодифицирован") Тогда
		ПараметрыЗагрузки.Вставить("ВариантМодифицирован", ВариантМодифицирован);
	КонецЕсли;

	Если Не ПараметрыЗагрузки.Свойство("ПользовательскиеНастройкиМодифицированы") Тогда
		ПараметрыЗагрузки.Вставить("ПользовательскиеНастройкиМодифицированы", ПользовательскиеНастройкиМодифицированы);
	КонецЕсли;

	Если Не ПараметрыЗагрузки.Свойство("Результат") Тогда
		ПараметрыЗагрузки.Вставить("Результат", Новый Структура);
	КонецЕсли;

	ПараметрыЗагрузки.Вставить("ОтчетОбъектИлиПолноеИмя", НастройкиОтчета.ПолноеИмя);
КонецПроцедуры

&НаСервере
Процедура ПоказатьОшибкиФормирования(ИнформацияОбОшибке)
	Если ТипЗнч(ИнформацияОбОшибке) = Тип("ИнформацияОбОшибке") Тогда
		ОписаниеОшибки = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке);
		ПодробноеПредставлениеОшибки = НСтр("ru = 'Отчет не сформирован по причине:'") + Символы.ПС
			+ ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
		Если ПустаяСтрока(ОписаниеОшибки) Тогда
			ОписаниеОшибки = ПодробноеПредставлениеОшибки;
		КонецЕсли;
	Иначе
		ОписаниеОшибки = ИнформацияОбОшибке;
		ПодробноеПредставлениеОшибки = "";
	КонецЕсли;

	ОтчетыКлиентСервер.ОтобразитьСостояниеОтчета(ЭтотОбъект, ОписаниеОшибки);

	Если Не ПустаяСтрока(ПодробноеПредставлениеОшибки) Тогда
		ВариантыОтчетов.ЗаписатьВЖурнал(УровеньЖурналаРегистрации.Предупреждение, ПодробноеПредставлениеОшибки,
			НастройкиОтчета.ВариантСсылка);
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Функция ТребуетсяСохранитьВариант()

	Если ВариантМодифицирован Тогда
		Возврат Истина;
	КонецЕсли;

	Если НастройкиОтчета.КлючПредопределенногоВарианта <> КлючТекущегоВарианта Тогда
		Возврат Ложь;
	КонецЕсли;

	ДополнительныеСвойства = Отчет.КомпоновщикНастроек.Настройки.ДополнительныеСвойства;
	Возврат ДополнительныеСвойства.Свойство("ФормаПараметрыОтбор") 
		И ЗначениеЗаполнено(ДополнительныеСвойства.ФормаПараметрыОтбор) Или РежимРасшифровки;

КонецФункции

&НаКлиенте
Процедура СохранитьНовыйИлиСуществующийВариантОтчетаИПродолжить(Команда)

	Если Не Элементы.СохранитьВариантКак.Видимость Тогда
		ПоказатьПредупреждение(, НСтр("ru = 'Невозможно выполнить действие, так как недоступно сохранение вариантов отчетов.'"));
		Возврат;
	КонецЕсли;

	Если Элементы.СохранитьВариант.Видимость Тогда
		Кнопки = Новый СписокЗначений;
		Кнопки.Добавить("СохранитьИПродолжить", НСтр("ru = 'Сохранить и продолжить'"));
		Кнопки.Добавить("Отмена", НСтр("ru = 'Отмена'"));
		ПараметрыВопроса = СтандартныеПодсистемыКлиент.ПараметрыВопросаПользователю();
		ПараметрыВопроса.ПредлагатьБольшеНеЗадаватьЭтотВопрос = Ложь;
		ПараметрыВопроса.КнопкаПоУмолчанию = "СохранитьИПродолжить";
		ПараметрыВопроса.Заголовок = ОтчетНаименованиеТекущегоВарианта;
		СтандартныеПодсистемыКлиент.ПоказатьВопросПользователю(
			Новый ОписаниеОповещения("Подключаемый_КомандаПослеОтветаНаВопросСохранитьВариант", ЭтотОбъект, Команда),
			НСтр("ru = 'Сохранить вариант отчета?'"), Кнопки, ПараметрыВопроса);
		Возврат;
	Иначе
		ПараметрыФормы = Новый Структура;
		ПараметрыФормы.Вставить("КлючОбъекта", НастройкиОтчета.ПолноеИмя);
		ПараметрыФормы.Вставить("КлючТекущихНастроек", КлючТекущегоВарианта);

		ОткрытьФорму("ХранилищеНастроек.ХранилищеВариантовОтчетов.ФормаСохранения", ПараметрыФормы, ЭтотОбъект,,,,
			Новый ОписаниеОповещения("Подключаемый_КомандаПослеСохраненияВарианта", ЭтотОбъект, Команда));
		Возврат;
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура Подключаемый_КомандаПослеОтветаНаВопросСохранитьВариант(Ответ, Команда) Экспорт

	Если Ответ = Неопределено Или Ответ.Значение <> "СохранитьИПродолжить" Тогда
		Возврат;
	КонецЕсли;

	СохранитьВариантОтчета();
	Подключаемый_Команда(Команда);

КонецПроцедуры

&НаКлиенте
Процедура Подключаемый_КомандаПослеСохраненияВарианта(Результат, Команда) Экспорт

	Если ТипЗнч(Результат) <> Тип("ВыборНастроек") Тогда
		Возврат;
	КонецЕсли;

	КлючТекущегоВарианта = Результат.КлючНастроек;

	СохранитьВариантОтчета(Истина);
	Подключаемый_Команда(Команда);

КонецПроцедуры

&НаКлиенте
Процедура СохранитьВариантОтчета(ПослеДобавленияНового = Ложь)

	СохранитьВариантОтчетаНаСервере(ПослеДобавленияНового);
	ПоказатьОповещениеПользователя(НСтр("ru = 'Вариант отчета сохранен'"), 
		?(Окно <> Неопределено, Окно.ПолучитьНавигационнуюСсылку(), Неопределено), Заголовок);

КонецПроцедуры

&НаСервере
Процедура СохранитьВариантОтчетаНаСервере(ПослеДобавленияНового = Ложь)

	КлючОтчета = НастройкиОтчета.ПолноеИмя;
	ОписаниеНастроек = ХранилищаНастроек.ХранилищеВариантовОтчетов.ПолучитьОписание(КлючОтчета, КлючТекущегоВарианта);

	Если ПослеДобавленияНового Тогда
		ОтчетНаименованиеТекущегоВарианта = ОписаниеНастроек.Представление;
		НовыйКомпоновщик = Новый КомпоновщикНастроекКомпоновкиДанных;
		НастройкиКД = НовыйКомпоновщик.ПолучитьНастройки();
		ПриСохраненииВариантаНаСервере(НастройкиКД);
	Иначе
		НастройкиКД = Отчет.КомпоновщикНастроек.Настройки;
	КонецЕсли;

	ХранилищаНастроек.ХранилищеВариантовОтчетов.Сохранить(КлючОтчета, КлючТекущегоВарианта, НастройкиКД, 
		ОписаниеНастроек);

	ВариантМодифицирован = Ложь;

КонецПроцедуры

&НаКлиенте
Процедура ОбновитьКомандыВыбораВариантовОбработчикОжидания()

	ОбновитьКомандыВыбораВариантов();

КонецПроцедуры

&НаСервере
Процедура ОбновитьКомандыВыбораВариантов()
	Если ОбщегоНазначения.РазделениеВключено() И Не ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
		Возврат;
	КонецЕсли;

	ВариантыФормы = РеквизитФормыВЗначение("ДобавленныеВарианты");
	ВариантыФормы.Колонки.Добавить("Найден", Новый ОписаниеТипов("Булево"));
	АвторизованныйПользователь = Пользователи.АвторизованныйПользователь();

	ПараметрыПоиска = Новый Структура;
	ПараметрыПоиска.Вставить("Отчеты", ОтчетыСервер.ЗначениеВМассив(НастройкиОтчета.ОтчетСсылка));

	Если НастройкиОтчета.Контекстный Тогда
		ПараметрыПоиска.Вставить("Контекст", КонтекстВарианта);
	КонецЕсли;
	
	ПараметрыПоиска.Вставить("ТолькоЛичные", Истина);

	ТаблицаВариантов = ВариантыОтчетов.ТаблицаВариантовОтчетов(ПараметрыПоиска);
	Если ТаблицаВариантов.Колонки.Найти("Наименование") = Неопределено Тогда
		ТаблицаВариантов.Колонки.НаименованиеВарианта.Имя = "Наименование";
	КонецЕсли;

	Если НастройкиОтчета.Внешний Тогда // Добавить предопределенные варианты внешнего отчета в таблицу вариантов.
		Для Каждого ЭлементСписка Из НастройкиОтчета.ПредопределенныеВарианты Цикл
			СтрокаТаблицы = ТаблицаВариантов.Добавить();
			СтрокаТаблицы.Наименование = ЭлементСписка.Представление;
			СтрокаТаблицы.КлючВарианта = ЭлементСписка.Значение;
		КонецЦикла;
	КонецЕсли;

	ТаблицаВариантов.Свернуть("Ссылка, КлючВарианта, Наименование, Автор, ТолькоДляАвтора");
	ТаблицаВариантов.Сортировать("Наименование Возр, КлючВарианта Возр");

	ОтчетыСервер.ДобавитьВариантыКонтекста(НастройкиОтчета.ОтчетСсылка, ТаблицаВариантов, ВариантыКонтекста);

	ГраницаМеню = ВариантыФормы.Количество() - 1;
	Для Каждого СтрокаТаблицы Из ТаблицаВариантов Цикл
		Найденные = ВариантыФормы.НайтиСтроки(Новый Структура("КлючВарианта, Найден", СтрокаТаблицы.КлючВарианта, Ложь));
		Если Найденные.Количество() = 1 Тогда
			ВариантФормы = Найденные[0];
			ВариантФормы.Найден = Истина;

			Кнопка = Элементы.Найти(ВариантФормы.ИмяКоманды);
			Кнопка.Видимость = Истина;
			Кнопка.Заголовок = СтрокаТаблицы.Наименование;
			Элементы.Переместить(Кнопка, Элементы.ГруппаВариантыОтчета);
			
			// Подменю Еще (Все действия).
			КнопкаЕще = Элементы.Найти(ВариантФормы.ИмяКоманды + "Еще");
			КнопкаЕще.Видимость = Истина;
			КнопкаЕще.Заголовок = СтрокаТаблицы.Наименование;
			Элементы.Переместить(КнопкаЕще, Элементы.ГруппаВариантыОтчетаЕще);
		Иначе
			ГраницаМеню = ГраницаМеню + 1;
			ВариантФормы = ВариантыФормы.Добавить();
			ЗаполнитьЗначенияСвойств(ВариантФормы, СтрокаТаблицы);
			ВариантФормы.Найден = Истина;
			ВариантФормы.ИмяКоманды = "ВыбратьВариант_" + Формат(ГраницаМеню, "ЧН=0; ЧГ=");

			Команда = Команды.Добавить(ВариантФормы.ИмяКоманды);
			Команда.Действие = "Подключаемый_ЗагрузитьВариантОтчета";

			Кнопка = Элементы.Добавить(ВариантФормы.ИмяКоманды, Тип("КнопкаФормы"), Элементы.ГруппаВариантыОтчета);
			Кнопка.Вид = ВидКнопкиФормы.КнопкаКоманднойПанели;
			Кнопка.ИмяКоманды = ВариантФормы.ИмяКоманды;
			Кнопка.Заголовок = СтрокаТаблицы.Наименование;
			
			// Подменю Еще.
			КнопкаЕще = Элементы.Добавить(ВариантФормы.ИмяКоманды + "Еще", Тип("КнопкаФормы"),
				Элементы.ГруппаВариантыОтчетаЕще);
			КнопкаЕще.Вид = ВидКнопкиФормы.КнопкаКоманднойПанели;
			КнопкаЕще.ИмяКоманды = ВариантФормы.ИмяКоманды;
			КнопкаЕще.Заголовок = СтрокаТаблицы.Наименование;

			ПостоянныеКоманды.Добавить(ВариантФормы.ИмяКоманды);
		КонецЕсли;

		Кнопка.Пометка = (КлючТекущегоВарианта = СтрокаТаблицы.КлючВарианта);
		Кнопка.ПоложениеВКоманднойПанели = ПоложениеКнопкиВКоманднойПанели.ВКоманднойПанели;

		КнопкаЕще.Пометка = (КлючТекущегоВарианта = СтрокаТаблицы.КлючВарианта);
		КнопкаЕще.ПоложениеВКоманднойПанели = ПоложениеКнопкиВКоманднойПанели.ВДополнительномПодменю;
	КонецЦикла;

	Найденные = ВариантыФормы.НайтиСтроки(Новый Структура("Найден", Ложь));
	Для Каждого ВариантФормы Из Найденные Цикл
		Кнопка = Элементы.Найти(ВариантФормы.ИмяКоманды);
		Кнопка.Пометка = Ложь;
		Кнопка.Видимость = Ложь;
		
		// Подменю Еще (Все действия).
		КнопкаЕще = Элементы.Найти(ВариантФормы.ИмяКоманды + "Еще");
		КнопкаЕще.Пометка = Ложь;
		КнопкаЕще.Видимость = Ложь;
	КонецЦикла;

	ВариантыФормы.Колонки.Удалить("Найден");
	ЗначениеВРеквизитФормы(ВариантыФормы, "ДобавленныеВарианты");
КонецПроцедуры

&НаСервере
Процедура ОбновитьИнформациюОВариантеОтчета()
	ДополнительныеСвойства = Отчет.КомпоновщикНастроек.Настройки.ДополнительныеСвойства;
	ДополнительныеСвойства.Вставить("КлючВарианта", КлючТекущегоВарианта);
	ДополнительныеСвойства.Вставить("ВариантНаименование", ОтчетНаименованиеТекущегоВарианта);

	НастройкиОтчета.ВариантСсылка = Неопределено;
	НастройкиОтчета.КлючЗамеров = Неопределено;
	НастройкиОтчета.ПредопределенныйСсылка = Неопределено;
	НастройкиОтчета.КлючПредопределенногоВарианта = Неопределено;
	НастройкиОтчета.Пользовательский = Ложь;
	НастройкиОтчета.ТипОтчета = Неопределено;

	Если ОбщегоНазначения.РазделениеВключено() И Не ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
		Возврат;
	КонецЕсли;

	Запрос = ВариантОтчетаПоСсылкеИКлючу(НастройкиОтчета.ОтчетСсылка, КлючТекущегоВарианта);

	Выборка = Запрос.Выполнить().Выбрать();
	Если Не Выборка.Следующий() Тогда

		Если НастройкиОтчета.Внешний Тогда
			Возврат;
		КонецЕсли;

		Запрос = ВариантОтчетаПоСсылкеИКлючу(НастройкиОтчета.ОтчетСсылка);

		Выборка = Запрос.Выполнить().Выбрать();
		Если Не Выборка.Следующий() Тогда
		
			// Отчет не подключен к подсистеме варианты отчетов (работает с ограничениями). 
			Возврат;

		КонецЕсли;

	КонецЕсли;

	КлючЗамеров = Выборка.КлючЗамеров;
	Если Не ЗначениеЗаполнено(КлючЗамеров) Тогда
		КлючЗамеров = ВариантыОтчетовСлужебный.КлючЗамеров(НастройкиОтчета.ПолноеИмя, КлючТекущегоВарианта);
	КонецЕсли;

	ЗаполнитьЗначенияСвойств(НастройкиОтчета, Выборка);
	НастройкиОтчета.КлючЗамеров = КлючЗамеров;
	ОписаниеНастроекОтчета = ОписаниеНастроекОтчета(НастройкиОтчета);

	Если РежимРасшифровки Тогда
		ОтчетНаименованиеТекущегоВарианта = ОписаниеНастроекОтчета.Наименование;
	КонецЕсли;

	ДополнительныеСвойства.Вставить("ВариантНаименование", ОтчетНаименованиеТекущегоВарианта);
	ДополнительныеСвойства.Вставить("КлючПредопределенногоВарианта",
		ОписаниеНастроекОтчета.КлючПредопределенногоВарианта);

КонецПроцедуры

&НаСервереБезКонтекста
Функция ВариантОтчетаПоСсылкеИКлючу(ОтчетСсылка, КлючВарианта = Неопределено)

	ТекстЗапроса =
	"ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 1
	|	ВариантыОтчетов.Ссылка КАК ВариантСсылка,
	|	ВариантыОтчетов.Представление КАК Наименование,
	|	ВариантыОтчетов.ПредопределенныйВариант.КлючЗамеров КАК КлючЗамеров,
	|	ВариантыОтчетов.ПредопределенныйВариант КАК ПредопределенныйСсылка,
	|	ВЫБОР
	|		КОГДА ВариантыОтчетов.Пользовательский
	|			ТОГДА ЕСТЬNULL(ВариантыОтчетов.Родитель.КлючВарианта, НЕОПРЕДЕЛЕНО)
	|		ИНАЧЕ ВариантыОтчетов.КлючВарианта
	|	КОНЕЦ КАК КлючПредопределенногоВарианта,
	|	ВариантыОтчетов.Пользовательский КАК Пользовательский,
	|	ВариантыОтчетов.ТипОтчета
	|ИЗ
	|	Справочник.ВариантыОтчетов КАК ВариантыОтчетов
	|ГДЕ
	|	ВариантыОтчетов.Отчет = &Отчет";

	Запрос = Новый Запрос;
	Запрос.УстановитьПараметр("Отчет", ОтчетСсылка);

	Если КлючВарианта <> Неопределено Тогда
		ТекстЗапроса = ТекстЗапроса + " И ВариантыОтчетов.КлючВарианта = &КлючВарианта"; // @Query-part1
		Запрос.УстановитьПараметр("КлючВарианта", КлючВарианта);
	КонецЕсли;

	Запрос.Текст = ТекстЗапроса;

	Возврат Запрос;

КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ПустойКлючВарианта()
	Возврат " - ";
КонецФункции

&НаКлиенте
Процедура ПраваПользователей(Команда)

	Если ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.УправлениеДоступом") Тогда
		МодульУправлениеДоступомСлужебныйКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль(
			"УправлениеДоступомСлужебныйКлиент");
		МодульУправлениеДоступомСлужебныйКлиент.ПоказатьПраваПользователейОтчета(
			НастройкиОтчета.ОтчетСсылка, НастройкиОтчета.ИспользуемыеТаблицы);
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура ПрименитьСхемуИзКонструктора(Результат)

#Если ТолстыйКлиентОбычноеПриложение Или ТолстыйКлиентУправляемоеПриложение Тогда
	Если ТипЗнч(Результат) <> Тип("СхемаКомпоновкиДанных") Тогда
		Возврат;
	КонецЕсли;

	НастройкиОтчета.АдресСхемы = ПоместитьВоВременноеХранилище(Результат, УникальныйИдентификатор);

	Путь = ПолучитьИмяВременногоФайла();

	ЗаписьXML = Новый ЗаписьXML;
	ЗаписьXML.ОткрытьФайл(Путь, "UTF-8");
	СериализаторXDTO.ЗаписатьXML(ЗаписьXML, Результат, "dataCompositionSchema",
		"http://v8.1c.ru/8.1/data-composition-system/schema");
	ЗаписьXML.Закрыть();

	ДвоичныеДанные = Новый ДвоичныеДанные(Путь);
	НачатьУдалениеФайлов(, Путь);

	Отчет.КомпоновщикНастроек.Настройки.ДополнительныеСвойства.Вставить("СхемаКомпоновкиДанных", ДвоичныеДанные);
	Отчет.КомпоновщикНастроек.Настройки.ДополнительныеСвойства.Вставить("ОтчетИнициализирован", Ложь);

	ПараметрыЗаполнения = Новый Структура;
	ПараметрыЗаполнения.Вставить("ПользовательскиеНастройкиМодифицированы", Истина);
	ПараметрыЗаполнения.Вставить("КомпоновщикНастроекКД", Отчет.КомпоновщикНастроек);
	ПараметрыЗаполнения.Вставить("ИмяСобытия", ОтчетыКлиентСервер.ИмяСобытияНастройкиПоУмолчанию());

	ОбновитьЭлементыФормыНастроек(ПараметрыЗаполнения);
#КонецЕсли

КонецПроцедуры

&НаКлиенте
Процедура ПрименитьНастройкиИзКонтекстногоМеню(Результат)

	Если ТипЗнч(Результат) <> Тип("Структура") Тогда
		Возврат;
	КонецЕсли;

	Действие = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Результат, "Действие");
	ИдентификаторВладельца = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Результат, "ИдентификаторВладельца");

	Если Не ВариантыОтчетовСлужебныйКлиент.ЭтоСобытиеКонтекстнойНастройки(Действие) 
		Или ИдентификаторВладельца <> УникальныйИдентификатор Тогда
		Возврат;
	КонецЕсли;

	УточнитьПризнакАвтоформированияОтчета(Результат);
	ПрименитьНастройкиИПереформироватьОтчет(Результат, Неопределено);

КонецПроцедуры

&НаКлиенте
Процедура ПослеВыбораПоля(ВыбранноеПоле, ДополнительныеПараметры) Экспорт

	ВариантыОтчетовСлужебныйКлиент.ПослеВыбораПоля(ВыбранноеПоле, ДополнительныеПараметры);

КонецПроцедуры

&НаКлиенте
Функция СвойстваЗаголовка()

	СвойстваРезультата = НастройкиОтчета.СвойстваРезультата; // см. ВариантыОтчетовСлужебный.СвойстваРезультатаОтчета
	Возврат СвойстваРезультата.Заголовки[ИмяТекущейОбластиЯчеек()];

КонецФункции

// Возвращаемое значение:
//   Строка
//
&НаКлиенте
Функция ИмяТекущейОбластиЯчеек()

	Область = Элементы.ОтчетТабличныйДокумент.ТекущаяОбласть;
	Если ТипЗнч(Область) = Тип("ОбластьЯчеекТабличногоДокумента") 
		И Область.ТипОбласти = ТипОбластиЯчеекТабличногоДокумента.Прямоугольник Тогда
		Возврат Область.Имя;
	КонецЕсли;

	Возврат "";

КонецФункции

&НаКлиенте
Процедура СброситьТекущуюОбласть()

#Если ВебКлиент Тогда

	ПолеДокумента = Элементы.ОтчетТабличныйДокумент;
	Область = ПолеДокумента.ТекущаяОбласть;

	Если ТипЗнч(Область) <> Тип("ОбластьЯчеекТабличногоДокумента") 
		Или Область.ТипОбласти <> ТипОбластиЯчеекТабличногоДокумента.Прямоугольник Тогда
		Возврат;
	КонецЕсли;

	СвойстваРезультата = НастройкиОтчета.СвойстваРезультата; // см. ВариантыОтчетовСлужебный.СвойстваРезультатаОтчета
	СвойстваЗаголовка = СвойстваРезультата.Заголовки[Область.Имя];
	Если ТипЗнч(СвойстваЗаголовка) <> Тип("Структура") Тогда
		Возврат;
	КонецЕсли;

	Если ОтчетТабличныйДокумент.ШиринаСтраницы > ОтчетТабличныйДокумент.ШиринаТаблицы Тогда
		ПолеДокумента.ТекущаяОбласть = ОтчетТабличныйДокумент.Область(1, ОтчетТабличныйДокумент.ШиринаТаблицы + 1);

	ИначеЕсли ОтчетТабличныйДокумент.ВысотаСтраницы > ОтчетТабличныйДокумент.ВысотаТаблицы Тогда
		ПолеДокумента.ТекущаяОбласть = ОтчетТабличныйДокумент.Область(ОтчетТабличныйДокумент.ВысотаТаблицы + 1, 1);

	КонецЕсли;

#КонецЕсли

КонецПроцедуры

&НаКлиенте
Процедура ПослеИзмененияСоставаБыстрыхНастроек(Результат, ДополнительныеПараметры) Экспорт

	Если ТипЗнч(Результат) <> Тип("Структура") Тогда
		Возврат;
	КонецЕсли;

	Если Результат.ВариантМодифицирован Или Результат.ВыводитьЗаголовкиНастроек <> ВыводитьЗаголовкиНастроек Тогда

		ВыводитьЗаголовкиНастроек = Результат.ВыводитьЗаголовкиНастроек;
		Если Результат.ВариантМодифицирован Тогда
			ВариантыОтчетовСлужебныйКлиент.ДобавитьНастройкиВСтек(ЭтотОбъект, 
				Результат.КомпоновщикНастроекКД.Настройки, Результат.ИмяСобытия);
		КонецЕсли;

		ОбновитьЭлементыФормыНастроек(Результат);
	КонецЕсли;

КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Функция КлючНастроекВариантаОтчета(ПолноеИмяОтчета, КлючВарианта)

	Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("%1/%2", ПолноеИмяОтчета, КлючВарианта);

КонецФункции

&НаСервере
Процедура СохранитьДанныеВНастройкахНаСервере(Настройки = Неопределено)

	КлючНастроек = КлючНастроекВариантаОтчета(НастройкиОтчета.ПолноеИмя, КлючТекущегоВарианта);
	СохранитьВыбранныйУровеньГруппировок(КлючНастроек, ВыбранныйУровеньГруппировок, РежимРасшифровки);
	СохранитьСостояниеОпцииВыводитьЗаголовкиНастроек(КлючНастроек, ВыводитьЗаголовкиНастроек, РежимРасшифровки);

	Если ТипЗнч(Настройки) = Тип("Соответствие") Тогда
		Настройки["ФормаНастроекРасширенныйРежим"] = НастройкиОтчета.ФормаНастроекРасширенныйРежим;
	КонецЕсли;

КонецПроцедуры

#Область ПереходМеждуНастройкамиСтека

&НаСервере
Процедура ОбновитьМенюПереходаМеждуИзменениямиНастроек()

	УдалитьКомандыМенюПереходаМеждуИзменениямиНастроек();
	ОпределитьДоступностьКомандПереходаМеждуИзменениямиНастроек();

	СтекНастроек.Сортировать("Порядок Убыв");

	ПройденаТекущаяНастройкаСтека = Ложь;
	СледующаяКоманда = Неопределено;

	Для Каждого Запись Из СтекНастроек Цикл

		Если Запись.Пометка Тогда
			ПройденаТекущаяНастройкаСтека = Истина;
		КонецЕсли;

		Если ПройденаТекущаяНастройкаСтека Тогда

			ГруппаДействий = Элементы.ГруппаОтменитьИзменениеНастроек;
			СледующаяКоманда = Элементы.УстановитьСтандартныеНастройки;

		Иначе

			ГруппаДействий = Элементы.ГруппаПовторитьИзменениеНастроек;

			Если ГруппаДействий.ПодчиненныеЭлементы.Количество() > 0 Тогда
				СледующаяКоманда = ГруппаДействий.ПодчиненныеЭлементы[0];
			КонецЕсли;

		КонецЕсли;

		ДобавитьКомандуПереходаМеждуИзменениямиНастроек(Запись, ГруппаДействий, СледующаяКоманда);

	КонецЦикла;

	ОбновитьСочетаниеКлавишКомандПереходаМеждуИзменениямиНастроек();

КонецПроцедуры

&НаСервере
Процедура УдалитьКомандыМенюПереходаМеждуИзменениямиНастроек()

	МаксимальныйРазмерСтекаНастроек = ВариантыОтчетовСлужебныйКлиентСервер.МаксимальныйРазмерСтекаНастроек();

	Для Порядок = 1 По МаксимальныйРазмерСтекаНастроек Цикл

		ИмяКоманды = ИмяКомандыПереходаМеждуИзменениямиНастроек(Порядок);

		Кнопка = Элементы.Найти(ИмяКоманды);

		Если Кнопка <> Неопределено Тогда
			Элементы.Удалить(Кнопка);
		КонецЕсли;

		Команда = Команды.Найти(ИмяКоманды);

		Если Команда <> Неопределено Тогда
			Команды.Удалить(Команда);
		КонецЕсли;

	КонецЦикла;

КонецПроцедуры

&НаСервере
Процедура ОпределитьДоступностьКомандПереходаМеждуИзменениямиНастроек()

	ТекущиеНастройкиСтека = ТекущиеНастройкиСтека();
	ТекущиеНастройкиСтекаОпределены = (ТекущиеНастройкиСтека.Количество() > 0);

	КнопкаУстановкиСтандартныхНастроек = Элементы.УстановитьСтандартныеНастройки;
	КнопкаУстановкиСтандартныхНастроек.Видимость = СтекНастроек.Количество() > 0;

	КнопкаУстановкиСтандартныхНастроек.Доступность = КнопкаУстановкиСтандартныхНастроек.Видимость
		И ТекущиеНастройкиСтекаОпределены;

	КнопкаУстановкиСтандартныхНастроек.Пометка = Не КнопкаУстановкиСтандартныхНастроек.Доступность;

КонецПроцедуры

&НаСервере
Процедура ДобавитьКомандуПереходаМеждуИзменениямиНастроек(ЗаписьСтекаНастроек, ГруппаДействий, СледующаяКоманда)

	ИмяКоманды = ИмяКомандыПереходаМеждуИзменениямиНастроек(ЗаписьСтекаНастроек.Порядок);
	ЗаголовокКоманды = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		"%1. %2", ЗаписьСтекаНастроек.Порядок, ЗаписьСтекаНастроек.ПредставлениеДействия);

	Команда = Команды.Найти(ИмяКоманды);

	Если Команда = Неопределено Тогда
		Команда = Команды.Добавить(ИмяКоманды);
	КонецЕсли;

	Команда.Действие = "Подключаемый_ПерейтиМеждуИзменениямиНастроек";
	Команда.Заголовок = ЗаголовокКоманды;

	Кнопка = Элементы.Найти(ИмяКоманды);

	Если Кнопка = Неопределено Тогда
		Кнопка = Элементы.Вставить(ИмяКоманды, Тип("КнопкаФормы"), ГруппаДействий, СледующаяКоманда);
	КонецЕсли;

	Кнопка.ИмяКоманды = ИмяКоманды;
	Кнопка.Заголовок = ЗаголовокКоманды;
	Кнопка.Доступность = Не ЗаписьСтекаНастроек.Пометка;
	Кнопка.Пометка = ЗаписьСтекаНастроек.Пометка;
	Кнопка.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.Нет);

КонецПроцедуры

&НаСервере
Функция ИмяКомандыПереходаМеждуИзменениямиНастроек(Порядок)

	Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		"%1%2", ПрефиксИмениКомандыПереходаМеждуИзменениямиНастроек(), Порядок);

КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ПрефиксИмениКомандыПереходаМеждуИзменениямиНастроек()

	Возврат "ПерейтиМеждуИзменениямиНастроек";

КонецФункции

&НаСервере
Процедура ОбновитьСочетаниеКлавишКомандПереходаМеждуИзменениямиНастроек()

	КнопкаУстановкиСтандартныхНастроек = Элементы.УстановитьСтандартныеНастройки;
	КнопкаУстановкиСтандартныхНастроек.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.Нет);

	СочетаниеКлавишОтменыДействия = Новый СочетаниеКлавиш(Клавиша.Z, Ложь, Истина, Ложь);
	СочетаниеКлавишПовтораДействия = Новый СочетаниеКлавиш(Клавиша.Y, Ложь, Истина, Ложь);

	ТекущиеНастройкиСтека = ТекущиеНастройкиСтека();

	Если ТекущиеНастройкиСтека.Количество() > 0 Тогда

		ПорядокКомандыТекущихНастроекСтека = ТекущиеНастройкиСтека[0].Порядок;

		СочетаниеКлавишУстановлено = УстановитьСочетаниеКлавишКомандыПереходаМеждуИзменениямиНастроек(
			ПорядокКомандыТекущихНастроекСтека - 1, СочетаниеКлавишОтменыДействия);

		Если Не СочетаниеКлавишУстановлено И ПорядокКомандыТекущихНастроекСтека = 1
			И Не КнопкаУстановкиСтандартныхНастроек.Пометка Тогда

			КнопкаУстановкиСтандартныхНастроек.СочетаниеКлавиш = СочетаниеКлавишОтменыДействия;

		КонецЕсли;

		УстановитьСочетаниеКлавишКомандыПереходаМеждуИзменениямиНастроек(
			ПорядокКомандыТекущихНастроекСтека + 1, СочетаниеКлавишПовтораДействия);

	ИначеЕсли СтекНастроек.Количество() > 0 И КнопкаУстановкиСтандартныхНастроек.Пометка Тогда

		УстановитьСочетаниеКлавишКомандыПереходаМеждуИзменениямиНастроек(1, СочетаниеКлавишПовтораДействия);

	КонецЕсли;

КонецПроцедуры

&НаСервере
Функция УстановитьСочетаниеКлавишКомандыПереходаМеждуИзменениямиНастроек(ПорядокКоманды, СочетаниеКлавиш)

	ИмяКоманды = ИмяКомандыПереходаМеждуИзменениямиНастроек(ПорядокКоманды);
	Кнопка = Элементы.Найти(ИмяКоманды);

	Если Кнопка = Неопределено Тогда
		Возврат Ложь;
	КонецЕсли;

	Кнопка.СочетаниеКлавиш = СочетаниеКлавиш;
	Возврат Истина;

КонецФункции

&НаСервере
Функция ТекущиеНастройкиСтека()

	Возврат СтекНастроек.НайтиСтроки(Новый Структура("Пометка", Истина));

КонецФункции

#КонецОбласти

&НаКлиенте
Процедура УточнитьПризнакАвтоформированияОтчета(ПараметрыОбновления)

	Если Не ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ПараметрыОбновления, "Переформировать", Ложь) Тогда
		ДопустимоеВремяДляАвтоформированияОтчета = 5; // секунд
		ВремяФормированияОтчета = НастройкиОтчета.СвойстваРезультата.ВремяФормирования;
		ПараметрыОбновления.Вставить("Переформировать", 
			ВремяФормированияОтчета <= ДопустимоеВремяДляАвтоформированияОтчета);
	КонецЕсли;

КонецПроцедуры

&НаСервереБезКонтекста
Функция СписокДоступныхФорматовСохраненияОтчета(ИндексФорматовСохраненияОтчета)

	ДоступныеФорматы = Новый СписокЗначений;

	ФорматыСохранения = СтандартныеПодсистемыСервер.НастройкиФорматовСохраненияТабличногоДокумента();

	Для Каждого ФорматСохранения Из ИндексФорматовСохраненияОтчета Цикл
		НайденноеОписание = ФорматыСохранения.Найти(ФорматСохранения.Ключ, "Расширение");
		ДоступныеФорматы.Добавить(НайденноеОписание.Расширение, НайденноеОписание.Представление,,
			НайденноеОписание.Картинка);
	КонецЦикла;

	Возврат ДоступныеФорматы;

КонецФункции

&НаСервере
Процедура ОбновитьДополнительныеСвойстваДанныхРасшифровки()

	Если ЗначениеЗаполнено(ОтчетДанныеРасшифровки) И ЭтоАдресВременногоХранилища(ОтчетДанныеРасшифровки) Тогда
		ДанныеРасшифровки = ПолучитьИзВременногоХранилища(ОтчетДанныеРасшифровки);
		Если ТипЗнч(ДанныеРасшифровки) = Тип("ДанныеРасшифровкиКомпоновкиДанных") Тогда
			ДополнительныеСвойства = ДанныеРасшифровки.Настройки.ДополнительныеСвойства;
			ДополнительныеСвойства.Вставить("ВариантНаименование", ОтчетНаименованиеТекущегоВарианта);
			ДополнительныеСвойства.Вставить("КлючВарианта", КлючТекущегоВарианта);
			ДополнительныеСвойства.Вставить("КонтекстВарианта", КонтекстВарианта);
			УдалитьИзВременногоХранилища(ОтчетДанныеРасшифровки);
			ОтчетДанныеРасшифровки = ПоместитьВоВременноеХранилище(ДанныеРасшифровки, УникальныйИдентификатор);
		КонецЕсли;
	КонецЕсли;

КонецПроцедуры

&НаСервере
Процедура ЗаполнитьПутьКФайлуВнешнегоОтчетаНаКлиенте(ОтчетОбъект)

	Если НастройкиОтчета.ТипОтчета = Перечисления.ТипыОтчетов.Дополнительный Тогда
		Возврат;
	КонецЕсли;

	СтруктураОбъекта = Новый Структура("ИспользуемоеИмяФайла", Неопределено);
	ЗаполнитьЗначенияСвойств(СтруктураОбъекта, ОтчетОбъект);

	Если Не ЗначениеЗаполнено(СтруктураОбъекта.ИспользуемоеИмяФайла)
	 Или СтрНачинаетсяС(СтруктураОбъекта.ИспользуемоеИмяФайла, "e1cib/")
	 Или СтрНачинаетсяС(СтруктураОбъекта.ИспользуемоеИмяФайла, "e1cib\") Тогда
		Возврат;
	КонецЕсли;

	ПутьКФайлуВнешнегоОтчетаНаКлиенте = СтруктураОбъекта.ИспользуемоеИмяФайла;

КонецПроцедуры

#КонецОбласти